如何解决NetworkOnMainThreadException错误的Andr​​oid? [英] How to solve NetworkOnMainThreadException error in android?

查看:131
本文介绍了如何解决NetworkOnMainThreadException错误的Andr​​oid?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用的JavaMail 来android系统中发送电子邮件。但它抛出异常的 NetworkOnMainThreadException 。如何解决这个例外?

MainActivity

 包com.aaa;
进口android.os.Bundle;
进口android.os.NetworkOnMainThreadException;
进口android.app.Activity;
进口android.util.Log;
进口android.view.Menu;
进口android.view.View;
进口android.widget.Toast;公共类MainActivity延伸活动{
私人邮件米;
@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);
    M =新邮件(mail@gmail.com,PWD);
}
 公共无效sendEmail(查看视图){
        的String [] = toArr {samp@gmail.com};
        m.setTo(toArr);
        m.setFrom(mail613@gmail.com);
        m.setSubject(主体);
        m.setBody(您的信息放在这里);        尝试{
            //m.addAttachment(\"/sdcard/myPicture.jpg);
            如果(m.send()){
                //成功
                Toast.makeText(MainActivity.this,邮件发送成功,Toast.LENGTH_LONG).show();
            }其他{
                //失败
                Toast.makeText(MainActivity.this,电子邮件未发送,Toast.LENGTH_LONG).show();
            }
        }赶上(例外五){
            //一些其他的问题
            //Toast.makeText(MainActivity.this,电子邮件未发送,Toast.LENGTH_LONG).show(E);
            Toast.makeText(MainActivity.this,+ E +,Toast.LENGTH_LONG).show();
            Log.e(的SendMail,e.getMessage(),E);
        }    } }

Mail.java

 包com.aaa;进口java.util.Date;
进口java.util.Properties;
进口javax.activati​​on.CommandMap;
进口的javax.activati​​on.DataHandler;
进口javax.activati​​on.DataSource;
进口javax.activati​​on.FileDataSource;
进口javax.activati​​on.MailcapCommandMap;
进口javax.mail.BodyPart;
进口javax.mail.Multipart;
进口javax.mail.PasswordAut​​hentication;
进口javax.mail.Session的;
进口javax.mail.Transport;
进口javax.mail.internet.InternetAddress;
进口javax.mail.internet.MimeBodyPart;
进口的javax.mail.internet.MimeMessage;
进口javax.mail.internet.MimeMultipart;公共类邮件扩展javax.mail.Authenticator {
私人字符串_user;
私人字符串_pass;私有String [] _​​to;
_from私人字符串;私人字符串_port;
私人字符串_sport;私人字符串_host;私人字符串_subject;
私人字符串_body;私人布尔_auth;私人布尔_debuggable;私人多部分_multipart;
公共邮件(){
    _host =smtp.gmail.com; //默认的SMTP服务器
    _port =465; //默认的SMTP端口
    _sport =465; //默认的SocketFactory端口    _user =; // 用户名
    _pass =; //密码
    _from =;从//发送电子邮件
    _subject =; // 电子邮件主题
    _body =; //邮件正文    _debuggable = FALSE;开启或关闭//调试模式 - 默认关闭
    _auth = TRUE; // SMTP认证 - 拖欠    _multipart =新MimeMultipart的();    //也有一些是错误的MAILCAP,JavaMail的找不到多部分/混合部分的处理程序,所以这一点需要添加。
    支持MailcapCommandMap MC =(支持MailcapCommandMap)CommandMap.getDefaultCommandMap();
    mc.addMailcap(text / html的;;的X Java的内容处理器= com.sun.mail.handlers.text_html);
    mc.addMailcap(文/ XML ;;的X Java的内容处理器= com.sun.mail.handlers.text_xml);
    mc.addMailcap(text / plain的;;的X Java的内容处理器= com.sun.mail.handlers.text_plain);
    mc.addMailcap(多重/ * ;;的X Java的内容处理器= com.sun.mail.handlers.multipart_mixed);
    mc.addMailcap(信息/ RFC822 ;;的X Java的内容处理器= com.sun.mail.handlers.message_rfc822);
    CommandMap.setDefaultCommandMap(MC);
}公共邮件(用户字符串,字符串传递){
    这个();    _user =用户;
    _pass =传递;
}公共布尔的send()抛出异常{
    属性道具= _setProperties();    !如果(_ user.equals()及与放大器;!_pass.equals()及与放大器; _to.length大于0&放大器;&放大器;!_from.equals()及与放大器;!_subject .equals()及与放大器;!_body.equals()){
        会话的会话= Session.getInstance(道具,这一点);        的MimeMessage味精=新的MimeMessage(会话);        msg.setFrom(新网际地址(_from));        网际地址[] = addressTo新的网际地址[_to.length]
        的for(int i = 0; I< _to.length;我++){
            addressTo [I] =新的网际地址(_to [I]);
        }
        msg.setRecipients(MimeMessage.RecipientType.TO,addressTo);        msg.setSubject(_subject);
        msg.setSentDate(新的Date());        //设置邮件正文
        BodyPart的messageBodyPart =新MimeBodyPart();
        messageBodyPart.setText(_body);
        _multipart.addBodyPart(messageBodyPart);        在消息//把部分
        msg.setContent(_multipart);        // 发电子邮件
        Transport.send(MSG);        返回true;
    }其他{
        返回false;
    }
}公共无效addAttachment(字符串文件名)抛出异常{
    BodyPart的messageBodyPart =新MimeBodyPart();
    数据源源=新FileDataSource(文件名);
    messageBodyPart.setDataHandler(新的DataHandler(源));
    messageBodyPart.setFileName(文件名);    _multipart.addBodyPart(messageBodyPart);
}@覆盖
公众的PasswordAut​​hentication的getPasswordAut​​hentication(){
    返回新的PasswordAut​​hentication(_user,_pass);
}私人性质_setProperties(){
    属性道具=新特性();    props.put(mail.smtp.host,_host);    如果(_debuggable){
        props.put(mail.debug为真);
    }    如果(_auth){
        props.put(mail.smtp.auth,真);
    }    props.put(mail.smtp.port,_port);
    props.put(mail.smtp.socketFactory.port,_sport);
    props.put(mail.smtp.socketFactory.class,javax.net.ssl​​.SSLSocketFactory);
    props.put(mail.smtp.socketFactory.fallback,假);    返回道具;
}// getter和setter
公共字符串getBody(){
    返回_body;
}公共无效setBody(字符串_body){
    this._body = _body;
}公共无效setTo(字符串[] toArr){
    this._to = toArr;
}公共无效setFrom(字符串字符串){
    this._from =串;
}公共无效SETSUBJECT(字符串字符串){
    this._subject =串;
}//更多的getter和setter ... ..
    }`


解决方案

您需要使用的 的AsyncTask 做你的所有网络操作。

您的网络操作会占用大量的时间,如果是主UI线程上完成的UI会得到响应。如果你的UI冻结很长一段时间,应用程序可能会得到由OS死亡。

这样的Andr​​oid 4+使得它强制使用一个后台线程来执行网络操作。

把code里面做网络活动 doInBacground() 和所有的AsyncTask的使用 的execute()

下面是你的AsyncTask会是什么样子:

 私有类的SendMail扩展的AsyncTask<字符串,整数,太虚> {
保护无效doInBackground(){
发电子邮件();
}保护无效onProgressUpdate(){
//当后台任务使任何进展称为
}在preExecute保护无效(){
//称为doInBackground()被启动之前
}
保护无效onPostExecute(){
//称为doInBackground()完成后
}
}

你可以在任何地方使用称之为 新的SendMail()执行();

I used javamail to send email in android. But it throws the Exception NetworkOnMainThreadException. How to solve this exception?

MainActivity

package com.aaa;
import android.os.Bundle;
import android.os.NetworkOnMainThreadException;
import android.app.Activity;
import android.util.Log; 
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity  {
private Mail m;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    m = new Mail("mail@gmail.com", "pwd");
}
 public void sendEmail(View view){
        String[] toArr = {"samp@gmail.com"};
        m.setTo(toArr);
        m.setFrom("mail613@gmail.com");
        m.setSubject("subject"); 
        m.setBody("your message goes here"); 

        try { 
            //m.addAttachment("/sdcard/myPicture.jpg");
            if(m.send()) { 
                // success
                Toast.makeText(MainActivity.this, "Email was sent successfully.", Toast.LENGTH_LONG).show(); 
            } else { 
                // failure
                Toast.makeText(MainActivity.this, "Email was not sent.", Toast.LENGTH_LONG).show(); 
            } 
        } catch(Exception e) { 
            // some other problem
            //Toast.makeText(MainActivity.this, "Email was not sent.", Toast.LENGTH_LONG).show(e);
            Toast.makeText(MainActivity.this, ""+e+"", Toast.LENGTH_LONG).show(); 
            Log.e("SendMail",e.getMessage(),e);
        } 

    }

 }

Mail.java

package com.aaa;

import java.util.Date; 
import java.util.Properties; 
import javax.activation.CommandMap; 
import javax.activation.DataHandler; 
import javax.activation.DataSource; 
import javax.activation.FileDataSource; 
import javax.activation.MailcapCommandMap; 
import javax.mail.BodyPart; 
import javax.mail.Multipart; 
import javax.mail.PasswordAuthentication; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeBodyPart; 
import javax.mail.internet.MimeMessage; 
import javax.mail.internet.MimeMultipart;

public class Mail extends javax.mail.Authenticator { 
private String _user; 
private String _pass; 

private String[] _to; 
private String _from; 

private String _port; 
private String _sport; 

private String _host; 

private String _subject; 
private String _body; 

private boolean _auth; 

private boolean _debuggable; 

private Multipart _multipart; 


public Mail() { 
    _host = "smtp.gmail.com"; // default smtp server 
    _port = "465"; // default smtp port 
    _sport = "465"; // default socketfactory port 

    _user = ""; // username 
    _pass = ""; // password 
    _from = ""; // email sent from 
    _subject = ""; // email subject 
    _body = ""; // email body 

    _debuggable = false; // debug mode on or off - default off 
    _auth = true; // smtp authentication - default on 

    _multipart = new MimeMultipart(); 

    // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added. 
    MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); 
    mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); 
    mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 
    mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); 
    mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); 
    mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822"); 
    CommandMap.setDefaultCommandMap(mc); 
} 

public Mail(String user, String pass) { 
    this(); 

    _user = user; 
    _pass = pass; 
} 

public boolean send() throws Exception { 
    Properties props = _setProperties(); 

    if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) { 
        Session session = Session.getInstance(props, this); 

        MimeMessage msg = new MimeMessage(session); 

        msg.setFrom(new InternetAddress(_from)); 

        InternetAddress[] addressTo = new InternetAddress[_to.length]; 
        for (int i = 0; i < _to.length; i++) { 
            addressTo[i] = new InternetAddress(_to[i]); 
        } 
        msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); 

        msg.setSubject(_subject); 
        msg.setSentDate(new Date()); 

        // setup message body 
        BodyPart messageBodyPart = new MimeBodyPart(); 
        messageBodyPart.setText(_body); 
        _multipart.addBodyPart(messageBodyPart); 

        // Put parts in message 
        msg.setContent(_multipart); 

        // send email 
        Transport.send(msg); 

        return true; 
    } else { 
        return false; 
    } 
} 

public void addAttachment(String filename) throws Exception { 
    BodyPart messageBodyPart = new MimeBodyPart(); 
    DataSource source = new FileDataSource(filename); 
    messageBodyPart.setDataHandler(new DataHandler(source)); 
    messageBodyPart.setFileName(filename); 

    _multipart.addBodyPart(messageBodyPart); 
} 

@Override 
public PasswordAuthentication getPasswordAuthentication() { 
    return new PasswordAuthentication(_user, _pass); 
} 

private Properties _setProperties() { 
    Properties props = new Properties(); 

    props.put("mail.smtp.host", _host); 

    if(_debuggable) { 
        props.put("mail.debug", "true"); 
    } 

    if(_auth) { 
        props.put("mail.smtp.auth", "true"); 
    } 

    props.put("mail.smtp.port", _port); 
    props.put("mail.smtp.socketFactory.port", _sport); 
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
    props.put("mail.smtp.socketFactory.fallback", "false"); 

    return props; 
} 

// the getters and setters 
public String getBody() { 
    return _body; 
} 

public void setBody(String _body) { 
    this._body = _body; 
} 

public void setTo(String[] toArr) {
    this._to = toArr;
}

public void setFrom(String string) {
    this._from = string;
}

public void setSubject(String string) {
    this._subject = string;
}

// more of the getters and setters ….. 
    } `

解决方案

You need to use an AsyncTask to do all your network operations.

Your network operation can take a lot of time and the UI would get unresponsive if it is done on the main UI thread. And if your UI freezes for a long time, the app might get killed by the OS.

Thus Android 4+ makes it mandatory to use a background thread to perform network operations.

Put the code to do the network activity inside doInBacground() and all the AsyncTask using execute().

Here is how your AsyncTask would look like :

private class SendMail extends AsyncTask<String, Integer, Void> {
     protected void doInBackground() {
        sendEmail();
 }

 protected void onProgressUpdate() {
    //called when the background task makes any progress
 }

  protected void onPreExecute() {
     //called before doInBackground() is started
 }
 protected void onPostExecute() {
     //called after doInBackground() has finished 
 }
  }

And you can call it anywhere using new SendMail().execute("");

这篇关于如何解决NetworkOnMainThreadException错误的Andr​​oid?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆