【问题标题】:Unfortunately, Msger has stopped. FATAL Exception: main [duplicate]不幸的是,Msger 已经停止了。致命例外:主要[重复]
【发布时间】:2012-11-16 01:29:33
【问题描述】:

可能重复:
android.os.NetworkOnMainThreadException

当我尝试从第一个 Activity 的侦听器运行我的第二个 Activity 时,main.xml 有一个致命异常。当我取出 runTcpClient();在 TcpClient Thread() 上它加载得很好。

我遇到了使用 aSyncTask 管理 UI 线程:Android UI aSyncTask

TcpClientJava.java 代码

package com.mesger;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;



public class TcpClient extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    runTcpClient();
    finish();
}

private static final int TCP_SERVER_PORT = 1234;
private void runTcpClient() {
    try {
        Socket s = new Socket("10.0.2.2", TCP_SERVER_PORT);
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        //send output msg
        String outMsg = "TCP connecting to " + TCP_SERVER_PORT + System.getProperty("line.separator"); 
        out.write(outMsg);
        out.flush();
        Log.i("TcpClient", "sent: " + outMsg);
        //accept server response
        String inMsg = in.readLine() + System.getProperty("line.separator");
        Log.i("TcpClient", "received: " + inMsg);
        //close connection
        s.close();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } 
}
//replace runTcpClient() at onCreate with this method if you want to run tcp client as a service
private void runTcpClientAsService() {
    Intent lIntent = new Intent(this.getApplicationContext(), TcpClientService.class);
    this.startService(lIntent);
}

}

LOGCAT

11-12 13:41:22.725: D/gralloc_goldfish(738): Emulator without GPU emulation detected.
11-12 13:42:32.409: D/AndroidRuntime(738): Shutting down VM
11-12 13:42:32.409: W/dalvikvm(738): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
11-12 13:42:32.465: E/AndroidRuntime(738): FATAL EXCEPTION: main
11-12 13:42:32.465: E/AndroidRuntime(738): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.i911.emergency.response/com.mesger.TcpClient}: android.os.NetworkOnMainThreadException
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.Looper.loop(Looper.java:137)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.ActivityThread.main(ActivityThread.java:4745)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.lang.reflect.Method.invokeNative(Native Method)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.lang.reflect.Method.invoke(Method.java:511)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-12 13:42:32.465: E/AndroidRuntime(738):  at dalvik.system.NativeStart.main(Native Method)
11-12 13:42:32.465: E/AndroidRuntime(738): Caused by: android.os.NetworkOnMainThreadException
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
11-12 13:42:32.465: E/AndroidRuntime(738):  at libcore.io.IoBridge.connect(IoBridge.java:112)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.startupSocket(Socket.java:566)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.tryAllAddresses(Socket.java:127)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.<init>(Socket.java:177)
11-12 13:42:32.465: E/AndroidRuntime(738):  at java.net.Socket.<init>(Socket.java:149)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.mesger.TcpClient.runTcpClient(TcpClient.java:32)
11-12 13:42:32.465: E/AndroidRuntime(738):  at com.mesger.TcpClient.onCreate(TcpClient.java:25)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.Activity.performCreate(Activity.java:5008)
11-12 13:42:32.465: E/AndroidRuntime(738):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-12 13:42:32.465: E/AndroidRuntime(738):  at     android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-12 13:42:32.465: E/AndroidRuntime(738):  ... 11 more

【问题讨论】:

    标签: android multithreading user-interface


    【解决方案1】:

    你不应该从主线程接触网络。 为网络操作实现 AsyncTask。

       private class MyInnerClass extends AsyncTask<String, Void, String> {
           @Override
           protected void onPreExecute() {
           super.onPreExecute();
    
           }
    
           @Override
           protected String doInBackground(String params) {
    
           return "Done";
           }
    
           @Override
           protected void onPostExecute(String result) {
           super.onPostExecute(result);
           }
       }
    

    调用 new MyInnerClass().execute();从你的主 Activity 和 android 将自动调用 onPreExecute() 在你的网络访问之前在这个方法中做任何你想做的事情。

    Android 将调用 doInBackground
    你是否在 doInBackground() 中与网络相关的东西,完成后它会自动调用 onPostExecute() 并且结果将作为参数传递给这个方法。

    【讨论】:

      【解决方案2】:
      Caused by: android.os.NetworkOnMainThreadException
      

      您正试图在主线程上执行一个可能很慢的网络操作,这在 Android 3.0+ 中成为了一个致命的异常。只需使用 AsyncTask 或 Loader 将 runTcpClient() 移动到新线程即可。

      这是一个示例:How to fix android.os.NetworkOnMainThreadException?


      试试这个:

      class TcpClientTask extends AsyncTask<Void, Void, Void> {
          private static final int TCP_SERVER_PORT = 1234;
          private boolean error = false;
      
          protected Void doInBackground(Void... arg0) {
              try {
                  Socket s = new Socket("10.0.2.2", TCP_SERVER_PORT);
                  BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
                  BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                  //send output msg
                  String outMsg = "TCP connecting to " + TCP_SERVER_PORT + System.getProperty("line.separator"); 
                  out.write(outMsg);
                  out.flush();
                  Log.i("TcpClient", "sent: " + outMsg);
                  //accept server response
                  String inMsg = in.readLine() + System.getProperty("line.separator");
                  Log.i("TcpClient", "received: " + inMsg);
                  //close connection
                  s.close();
              } catch (UnknownHostException e) {
                  error = true;
                  e.printStackTrace();
              } catch (IOException e) {
                  error = true;
                  e.printStackTrace();
              }
              return null;
          }
      
          protected void onPostExecute() {
              if(error) {
                  // Something bad happened
              }
              else {
                  // Success
              }
      
          }
      }
      

      要使用它,请致电:new TcpClientTask().execute();


      我还有 1 个问题。 String inMsg = in.readLine() + System.getProperty("line.separator"); 接收消息,我将如何设置它以每 15 毫秒获取一次,或者任何稳定的东西以继续接收数据。

      我不确定您要做什么。但我注意到你只调用一次readLine(),如果你想读取多行,使用循环:

      StringBuilder msg = new StringBuilder();
      String line;
      while((line = in.readLine()) != null) // Keep reading until the end of the file is reached
          msg.append(in.readLine()).append(System.getProperty("line.separator"));
      

      StringBuilders 在将字符串添加在一起时会产生更少的开销,当您想要获取整个消息时,只需使用 msg.toString()

      【讨论】:

      • 我看到了那个帖子,我尝试按照他们的建议去做,但没有成功?我对 Android 还是很陌生,我将如何在我的代码中实现 aSyncTask?我也应该改变我所有的 Activty 以这种方式运行吗?
      • 我下班后试试看,然后告诉你。很高兴终于能完成这项工作!山姆。你摇滚!
      • 我没有测试过这个。因此,如果它不起作用,请告诉我,我将自己实现并修复它。
      • 当我使用此代码时,我得到描述资源路径位置类型类型 TcpClient.TcpClientTask 必须实现继承的抽象方法 AsyncTask.doInBackground(Void...) TcpClient.java /mesger/src/com/mesger 第 32 行 Java 问题
      • 使用protected Void doInBackground(Void... arg0) {并将return null;添加到doInBackground()的末尾。
      【解决方案3】:

      尝试使用 Small Piece Of Code。但这不是一个好习惯。

          StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
         .detectNetwork()
         .permitNetwork() //permit Network access 
         .build());
      

      您可以使用 AsynTask 或任何线程概念。 Its May Help

      【讨论】:

      猜你喜欢
      • 2012-08-19
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 2020-06-29
      • 1970-01-01
      相关资源
      最近更新 更多