主线程中的致命异常

时间:2013-12-19 06:43:49

标签: android networking

我是android新手。我的项目与网络有关。我收到了这个错误 致命的例外:主要

android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java1133)

... ...

我的代码是:

package com.example.simpleclientactivity;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;

    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;

    public class SimpleClientActivity extends Activity {

     private Socket client;
     private PrintWriter printwriter;
     private EditText textField1;
     private Button button;
     private String messsage;

     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);

      textField1 = (EditText) findViewById(R.id.editText1); //reference to the text field
      button = (Button) findViewById(R.id.button1);   //reference to the send button

      //Button press event listener
      button.setOnClickListener(new View.OnClickListener() {

       public void onClick(View v) {

          Context context = getApplicationContext();
          CharSequence text = "Hello toast!";
          int duration = Toast.LENGTH_SHORT;

          Toast toast = Toast.makeText(context, text, duration);
          toast.show();
          messsage = textField1.getText().toString(); //get the text message on the text field      
          textField1.setText("");      //Reset the text field to blank

          try {

                 client = new Socket("10.0.2.2", 4444);  //connect to server
                 printwriter = new PrintWriter(client.getOutputStream(),true);
                 printwriter.write(messsage);  //write the message to output stream

                 printwriter.flush();
                 printwriter.close();
                 client.close();   //closing the connection

                } catch (UnknownHostException e) {
                 e.printStackTrace();
                } catch (IOException e) {
                 e.printStackTrace();
                }
        }
      });

     }
    }

这是main.xml代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"`enter code here`
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="83dp"
        android:ems="10"
        android:text="Client" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="53dp"
        android:text="Send" />

</RelativeLayout>

单击按钮后,甚至没有显示Toast消息。但是它在android.os.NetworkOnMainThreadException中显示错误。

4 个答案:

答案 0 :(得分:1)

试试这个..

当应用程序尝试在其主线程上执行网络操作时抛出此异常

 button.setOnClickListener(new View.OnClickListener() {

       public void onClick(View v) {

          Context context = getApplicationContext();
          CharSequence text = "Hello toast!";
          int duration = Toast.LENGTH_SHORT;

          Toast toast = Toast.makeText(context, text, duration);
          toast.show();
          messsage = textField1.getText().toString(); //get the text message on the text field      
          textField1.setText("");      //Reset the text field to blank

            new MyClass().execute(messsage);


        }
      });

MyClass.class AsyncTask

class MyClass extends AsyncTask<String, Void, String> {

    private Exception exception;

    protected String doInBackground(String... messsage) {
        try {

                 client = new Socket("10.0.2.2", 4444);  //connect to server
                 printwriter = new PrintWriter(client.getOutputStream(),true);
                 printwriter.write(messsage);  //write the message to output stream

                 printwriter.flush();
                 printwriter.close();
                 client.close();   //closing the connection

                } catch (UnknownHostException e) {
                 e.printStackTrace();
                } catch (IOException e) {
                 e.printStackTrace();
                }
    }

    protected void onPostExecute(String result) {
        // TODO: check this.exception 
        // TODO: do something with the feed
    }
}

您无法在Honeycomb上的UI线程上执行网络IO。从技术上讲,它在早期版本的Android上可能 ,但这是一个非常糟糕的主意,因为它会导致您的应用停止响应,并可能导致操作系统因为行为不当而导致您的应用程序被杀。您需要运行后台进程或使用AsyncTask在后台线程上执行网络事务。

Android开发者网站上有一篇关于Painless Threading的文章,这是对此的一个很好的介绍,它将为您提供比这里实际提供的更好的答案。

答案 1 :(得分:0)

您必须在线程上放置访问互联网的代码

new Thread(new Runnable(){
  @Override
  public void run(){
    //your code that access internet here
  }
}).start();

答案 2 :(得分:0)

试试这段代码

   package com.example.simpleclientactivity;
   import java.io.IOException;
  import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class SimpleClientActivity extends Activity {

 private Socket client;
 private PrintWriter printwriter;
 private EditText textField1;
 private Button button;
 private String messsage;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  textField1 = (EditText) findViewById(R.id.editText1); //reference to the text field
  button = (Button) findViewById(R.id.button1);   //reference to the send button

  //Button press event listener
  button.setOnClickListener(new View.OnClickListener() {

   public void onClick(View v) {

      Context context = getApplicationContext();
      CharSequence text = "Hello toast!";
      int duration = Toast.LENGTH_SHORT;

      Toast toast = Toast.makeText(context, text, duration);
      toast.show();
      messsage = textField1.getText().toString(); //get the text message on the text field      
      textField1.setText("");      //Reset the text field to blank

    new GetCategory().execute(message);
    }
  });

 }


    //add inner class

   class GetCategory extends AsyncTask<Void, Void, ArrayList<AbstractDetail>>{



    protected  ArrayList<AbstractDetail>  doInBackground(String... messsage) {
        try {

             client = new Socket("10.0.2.2", 4444);  //connect to server
             printwriter = new PrintWriter(client.getOutputStream(),true);
             printwriter.write(messsage);  //write the message to output stream

             printwriter.flush();
             printwriter.close();
             client.close();   //closing the connection

            } catch (UnknownHostException e) {
             e.printStackTrace();
            } catch (IOException e) {
             e.printStackTrace();
            }
        return null;

    }

    protected void onPostExecute(ArrayList<AbstractDetail> result)
    {


        }

    }


}






}

答案 3 :(得分:0)

问题

<强>解决方案

  • 通过Thread.创建新主题并访问网络 OR
  • 使用AsyncTask doInBackgroung()上执行与网络相关的工作,并使用更新的用户界面 onPostExecute()