首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Networking is in AsyncTask和NetworkOnMainThreadException错误

Networking is in AsyncTask和NetworkOnMainThreadException错误
EN

Stack Overflow用户
提问于 2012-09-19 20:41:07
回答 3查看 1.2K关注 0票数 1

我想从远程数据库中获取一些数据,并且在我的activity的AsyncTask子类中有一些网络,但是当我试图加载我的程序时,它显示为NetworkOnMainThreadException。

下面是我的代码:

代码语言:javascript
复制
public class MyMapLocationActivity extends MapActivity {

private MapView mapView;
private static String url_product_details = "http://myurl.com/readfromdb";
private static final String TAG_SUCCESS = "success";
private static final String TAG_LATITUDE = "latitude";
private static final String TAG_LONGITUDE = "longitude";
private static final String TAG_POINT = "point";

    JSONParser jsonParser = new JSONParser();

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main); 

    mapView = (MapView) findViewById(R.id.mapview);
    mapView.setBuiltInZoomControls(true);

    ReadLocations Read = new ReadLocations();
    Read.execute();
}

//And my networking AsyncTask:

class ReadLocations extends AsyncTask<String, String, String> {


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }


   @Override
    protected String doInBackground(String... args) {
       Log.d("debug", "START DOINBACKGROUND");


       runOnUiThread(new Runnable() {
           public void run() {
               // Check for success tag
               int success;
               try {

                   // Building Parameters
                   List<NameValuePair> params = new ArrayList<NameValuePair>();
                   params.add(new BasicNameValuePair("id", "16"));

                   // getting product details by making HTTP request
                   // Note that product details url will use GET request
                   Log.d("debug", "before http request");

                   JSONObject json = jsonParser.makeHttpRequest(
                           url_product_details, "POST", params);
                   Log.d("debug", "after http request");

                   // json success tag
                   success = json.getInt(TAG_SUCCESS);

                   if (success == 1) {
                       // successfully received product details
                       JSONArray productObj = json
                               .getJSONArray(TAG_POINT); // JSON Array

                       // get first product object from JSON Array
                       JSONObject product = productObj.getJSONObject(0);

                   }else{
                       // product with pid not found
                   }
               } catch (JSONException e) {
                   e.printStackTrace();
               }
           }
       });

        return null; 
    }



  @Override
    protected void onPostExecute(String text) {
        // dismiss the dialog once done
   Log.d("debug", "ONPOSTEXECUTE");

    }

LogCat显示“在http请求之前”,但不显示我的“在http请求之后”检查。

怎么啦?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-19 20:42:41

您的网络代码位于应用程序的MainUiThread上,而不在工作线程中...

删除

代码语言:javascript
复制
runOnUiThread(new Runnable() {
           public void run() {

来自doInBackground()

并将WebRequest代码仅放在doInBackground() of AsyncTask中。

更新:

实际上,您在doInBackground()上的AsyncTask实现是错误的。因为doInBackground()在工作线程中运行,用于冗长的和网络相关的操作。并且您正在尝试使用不在规则中的runOnUiThread()从它运行MainUiThread。如果你想做任何与UI相关的工作,可以使用onPostExecute()onPreExecute()和ASyncTask的其他方法。

票数 5
EN

Stack Overflow用户

发布于 2012-09-19 20:45:15

试试下面的代码:

代码语言:javascript
复制
@Override
protected String doInBackground(String... args) {
   Log.d("debug", "START DOINBACKGROUND");

           // Check for success tag
           int success;
           try {

               // Building Parameters
               List<NameValuePair> params = new ArrayList<NameValuePair>();
               params.add(new BasicNameValuePair("id", "16"));

               // getting product details by making HTTP request
               // Note that product details url will use GET request
               Log.d("debug", "before http request");

               JSONObject json = jsonParser.makeHttpRequest(
                       url_product_details, "POST", params);
               Log.d("debug", "after http request");

               // json success tag
               success = json.getInt(TAG_SUCCESS);

               if (success == 1) {
                   // successfully received product details
                   JSONArray productObj = json
                           .getJSONArray(TAG_POINT); // JSON Array

                   // get first product object from JSON Array
                   JSONObject product = productObj.getJSONObject(0);

               }else{
                   // product with pid not found
               }
           } catch (JSONException e) {
               e.printStackTrace();
           }

           return null; 
}

代码的问题在于,您只能在主UI线程上运行网络函数,方法是使用以下代码:runOnUiThread(new Runnable() {...}

doInBackground()自动在单独的后台非UI线程上运行,您不需要显式创建线程。

票数 1
EN

Stack Overflow用户

发布于 2012-09-19 20:43:03

这是因为您正在UI线程上运行网络代码...您的doInBackground显式地在UI线程上运行网络代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12494902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档