【问题标题】:NetworkOnMainThreadException in IntetentServiceIntetentService 中的 NetworkOnMainThreadException
【发布时间】:2013-02-18 11:33:20
【问题描述】:

我有一个执行网络操作 (HTTP POST) 的 IntentService,但它显示了 NetworkOnMainThreadException。如果我是对的,IntentService 将在单独的线程上运行。谁能说出为什么会抛出这个异常?我的代码是:

public class UpdateService extends IntentService {
public static final int UPDATE_PROGRESS = 8344;
BroadcastReceiver broadcastReceiver;
public UpdateService() {
    super("UpdateService");
}
@Override
protected void onHandleIntent(Intent intent) {

        if (broadcastReceiver == null) {

            broadcastReceiver = new BroadcastReceiver() {

                @Override
                public void onReceive(Context context, Intent intent) {

                    Bundle extras = intent.getExtras();

                    NetworkInfo info = (NetworkInfo) extras.getParcelable("networkInfo");

                    State state = info.getState();
                    if (state == State.CONNECTED) {

                        onNetworkUp();

                    } else {

                    }
                }
            };

            final IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
            registerReceiver(broadcastReceiver, intentFilter);
        }
}

@Override
public void onDestroy(){
    unregisterReceiver(broadcastReceiver);
    }

void onNetworkUp(){
    String aDataRow = "";
    try {
        File myFile = new File( Environment.getExternalStorageDirectory().getPath() + "/myFile.txt");
        FileReader fr = new FileReader(myFile);
        BufferedReader myReader = new BufferedReader(fr);   
        while ((aDataRow = myReader.readLine()) != null) 
        updateLyne(aDataRow); //
        fr.close();
    } catch (Exception e) {
        Log.e("onNetworkUp",e.toString());
    }   


    void updateLyne(String aDataRow){
    JSONParser jsonParser = new JSONParser();
    String[] words = aDataRow.split(" ");
    pid = words[1];
    String rtime = aDataRow;
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair(TAG_PID, pid));
    params.add(new BasicNameValuePair(TAG_TIME, rtime));

    JSONObject json = null;
    if (words[0].equalsIgnoreCase("cancel")){
        json = jsonParser.makeHttpRequest(url_cancel, "POST", params);                  
    }
    else{
        Log.d("empty","file empty!!");
    }

    try {
        int success = json.getInt("success");

        if (success == 1) {
            delLine(aDataRow); // delete the line
        } else {
            Log.d("pid="+pid+" not on board", "failed in deleting");
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

}
}

JSONParser.java 如下所示

    public class JSONParser {

static InputStream is = null;
static JSONObject jObj = null;
static String json = "";

// constructor
public JSONParser() {

}

// function get json from url
public JSONObject makeHttpRequest(String url, String method,
        List<NameValuePair> params) {

    // Making HTTP request
    try {

        // check for request method
        if(method == "POST"){

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new UrlEncodedFormEntity(params));

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();
        }

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    // try parse the string to a JSON object
    try {
        jObj = new JSONObject(json);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

    // return JSON String
    return jObj;

}
    }

【问题讨论】:

  • 您是否在 Android 3.0 或更高版本上尝试此代码?
  • @Bigflow。是的..我正在写ICS..我猜你只会在3.0以上得到这样的例外..
  • 对,没错,看sajmon_d的回答。

标签: android intentservice networkonmainthread


【解决方案1】:

问题是你没有在onHandleIntent() 中运行网络请求,你只是创建了一个BroadcastReceiver 的实例并注册它。实际的网络请求不会在那里运行。它会在BroadcastReceiver 收到一条消息时运行,这发生在 UI 线程上。一个正确的方案是在其他地方创建你的BroadcastReceiver,当收到一条消息时,启动一个IntentService,它在onHandleIntent() 中执行一个网络调用——然后它确实会在工作线程上运行。希望这会有所帮助。

【讨论】:

  • Thaks @Egor.. 这有帮助。但我有一个在主线程中运行的活动,我希望该服务一直在后台运行,监控网络状态。那么是否可以在另一个服务中创建BroadcastReceiver 并调用IntentService?或者有没有其他方法可以在不使用主线程的情况下监控网络状态?
  • @nidhin,这里有一个很好的关于监控连接状态的参考:developer.android.com/training/monitoring-device-state/… 正如你所看到的,你需要一个 BroadcastReceiver 来监控连接。
猜你喜欢
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
  • 2014-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多