使用单独的线程时,我得到`android.os.NetworkOnMainThreadException`

时间:2013-09-26 16:33:34

标签: android ui-thread android-handler

在我的活动中,我使用了一个处理程序

Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg)  {   
               //do GUI stuff, edit views, etc..
    }
};

我还有一个Runnable,它发布到php并等待json响应

Runnable runnable3 = new Runnable() {
        public void run() { 
            JSONParserArray jsonParserRun = new JSONParserArray();
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("p1", "myParam1"));
            try {
                String link = "http://mylink.com/someFileOnServer.php";
                JSONArray jArray = jsonParserRun.makeHttpRequest(link , "POST",
                        params);
                if (jArray != null && jArray.length() != 0) {
                } else {
                    //either null (because of throwing exception) or empty
                }
            } catch (Exception e) {
            }
        }
        handler.sendEmptyMessage(0);
        handler.postDelayed(runnable, 30000);
  }

我每隔30秒重复一次任务,最后在我的onCreate()内部创建一个线程并将其传递给Runnable

@Override
public void onCreate(Bundle savedInstanceState) {
            //other stuff
    Thread t = new Thread(runnable3);
    t.start();
}

此代码抛出android.os.NetworkOnMainThreadException,甚至认为我正在启动一个新线程并将Runnable传递给它。 JSONParserArray类在其他情况下工作正常(所以不用担心)

但是,当我在Runnable中运行此方法时,它运行正常。

private boolean hasActiveInternetConnection() {
        try {
            new Socket().connect(new InetSocketAddress("google.com", 80), 3000);    
            return true;
        } catch (Exception e) {
            Log.i("tag", e.toString());
            return false;
        }
    }

2 个答案:

答案 0 :(得分:6)

Handler.postDelayed()执行Runnable创建Thread的{​​{1}}。在您的情况下,您可以在UI线程上的Activity中创建它。所以第一次,Handler在一个单独的线程中执行,但第二次在UI线程中执行。

答案 1 :(得分:-3)

还有另一种方法可以克服异常。

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); 

在你的清单中

<uses-permission android:name="android.permission.INTERNET"/>