Android - android.os.NetworkOnMainThreadException

Gee*_*Out 48 android networkonmainthread

我有这个例外,我正在阅读这个问题的线程,这看起来很混乱:

如何修复android.os.NetworkOnMainThreadException?

我已将此行添加到我的清单中:

<uses-permission android:name="android.permission.INTERNET" />
Run Code Online (Sandbox Code Playgroud)

在讨论中,他们讨论了应用程序无法进行网络连接的主要执行线程.我想知道的是如何重构我的代码,以便它与Android良好实践一致.

这是我的Activity类:

package com.problemio;

import java.io.InputStream;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class LoginActivity extends Activity 
{
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);

        // Show form for login_email
        final EditText loginEmail = (EditText) findViewById(R.id.login_email);  
        String name = loginEmail.getText().toString();  

        // Show field for password  
        final EditText password = (EditText) findViewById(R.id.password);  
        String text = password.getText().toString();                  

        // Show button for submit
        Button submit = (Button)findViewById(R.id.submit);   




        // Show options for create-profile and forgot-password




        submit.setOnClickListener(new Button.OnClickListener() 
        {  
           public void onClick(View v) 
           {
              String email = loginEmail.getText().toString();
              String pass = password.getText().toString(); 
              sendFeedback(pass, email);
            }
        });        
    }


    public void sendFeedback(String pass , String email) 
    {  
        Log.d( "1" , pass );
        Log.d( "1" , email );

        // Go to db and check if these r legit
        // How do I do that? :)
        ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();  
        postParameters.add(new BasicNameValuePair("username", email ));  
        postParameters.add(new BasicNameValuePair("password", pass ));

        String responseString = null;

        try 
        {  
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("myUrl");

            // no idea what this does :)
            httppost.setEntity(new UrlEncodedFormEntity(postParameters));

            // This is the line that send the request
            HttpResponse response = httpclient.execute(httppost);

            HttpEntity entity = response.getEntity();            

            InputStream is = entity.getContent();
        } 
        catch (Exception e) 
        {     
            Log.e("log_tag", "Error in http connection "+e.toString());
        }        
    }          
}
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么,我怎么能解决它?:) 谢谢!!

小智 56

NetworkOnMainThreadException:应用程序尝试在其主线程上执行网络操作时引发的异常.

你应该在asynctask上调用sendfeedback方法然后只有上面的代码才能工作.由于网络服务器花费了大量时间来响应主线程变得反应迟钝.要避免它,你应该在另一个线程上调用它.因此asynctask更好.

这里是链接,说明如何使用的AsyncTask

  • `AsyncTask` 现已弃用,更好的替代方案是使用 `java.util.concurrent.Executors` 在另一个线程中执行网络任务。 (2认同)

pra*_*upd 34

当您的应用尝试在主线程中进行网络操作时,将引发NetworkOnMainThreadException.

要解决此问题,您可以在Activity中使用私有内部类,android.os.AsyncTask<Params, Progress, Result>该内部类将扩展,这将执行服务器调用.

有点像,

private class SendfeedbackJob extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String[] params) {
        // do above Server call here
        return "some message";
    }

    @Override
    protected void onPostExecute(String message) {
        //process message
    }
}
Run Code Online (Sandbox Code Playgroud)

然后从submit.setOnClickListener下面调用上面的类,

SendfeedbackJob job = new SendfeedbackJob();
job.execute(pass, email);
Run Code Online (Sandbox Code Playgroud)

的AsyncTask

参考

AsyncTask doc

AsyncTask Android示例

  • 嘿!你怎么能看到你的笔迹:) (12认同)
  • 来吧,伙伴们,那太美了:) (4认同)

AnD*_*nDx 11

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}
Run Code Online (Sandbox Code Playgroud)

  • 不是真的,当你只是需要一个小测试,并为此创建一个新的小型android项目.. :) (7认同)

Bla*_*elt 8

 try 
    {  
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("myUrl");

        // no idea what this does :)
        httppost.setEntity(new UrlEncodedFormEntity(postParameters));

        // This is the line that send the request
        HttpResponse response = httpclient.execute(httppost);

        HttpEntity entity = response.getEntity();            

        InputStream is = entity.getContent();
    } 
    catch (Exception e) 
    {     
        Log.e("log_tag", "Error in http connection "+e.toString());
    }        
Run Code Online (Sandbox Code Playgroud)

这是你的问题.从api 11开始,此异常将通知您在ui线程(类中的http通信)上运行长任务,并且根据新的StrictGuard策略,这是不可能的.所以你有两个不同的选择

  1. 使用线程或aynctask来执行长期任务(更好的方法)