3

我正在制作一个使用互联网检索信息的应用程序。当我尝试在 3.0 及更高版本上运行它时,我得到了一个NetworkOnMainThreadException,因此尝试使用 AsyncTask 进行设置,但它仍然给出异常,我不知道出了什么问题。奇怪的是,我在AsyncTask 内部的这个线程 Android NetworkOnMainThreadException上读到,如果您只是android:targetSdkVersion="10"从清单文件中删除该语句,它将能够运行。这可行,但我认为它不是以这种方式解决问题的正确解决方案。

因此,如果有人能告诉我我在 AsyncTask 上做错了什么,我将不胜感激。此外,如果有人知道为什么删除清单中的语句使其起作用,我也对此很感兴趣。

我的代码如下所示:编辑:更新的代码。

public class MainActivity extends Activity {

static ArrayList<Tumblr> tumblrs;
ListView listView;
TextView footer;
int offset = 0;
ProgressDialog pDialog;
View v;
String responseBody = null;
HttpResponse r;
HttpEntity e;
String searchUrl;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    final ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    final NetworkInfo activeNetwork = conMgr.getActiveNetworkInfo();
    if (activeNetwork != null && activeNetwork.isConnected()) {

        setContentView(R.layout.main);

        try {
            tumblrs = getTumblrs();
            listView = (ListView) findViewById(R.id.list);
            View v = getLayoutInflater().inflate(R.layout.footer_layout,
                    null);
            footer = (TextView) v.findViewById(R.id.tvFoot);
            listView.addFooterView(v);
            listView.setAdapter(new UserItemAdapter(this, R.layout.listitem));

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        new GetChicks().execute();
        footer.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                new loadMoreListView().execute();
            }
        });

    } else {
        setContentView(R.layout.nonet);

    }

}

public class UserItemAdapter extends ArrayAdapter<Tumblr> {

    public UserItemAdapter(Context context, int imageViewResourceId) {
        super(context, imageViewResourceId, tumblrs);

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {

            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.listitem, null);

        }

        Tumblr tumblr = tumblrs.get(position);
        if (tumblr != null) {

            ImageView image = (ImageView) v.findViewById(R.id.avatar);

            if (image != null) {
                image.setImageBitmap(getBitmap(tumblr.image_url));

            }
        }

        return v;
    }
}

public Bitmap getBitmap(String bitmapUrl) {
    try {
        URL url = new URL(bitmapUrl);
        return BitmapFactory.decodeStream(url.openConnection()
                .getInputStream());
    } catch (Exception ex) {
        return null;
    }
}

public ArrayList<Tumblr> getTumblrs() throws ClientProtocolException,
        IOException, JSONException {
    searchUrl = "http://api.tumblr.com/v2/blog/factsandchicks.com/posts?api_key=rTZsymOWtMudbb5tql2U20qQ5ooYLPYVNnL3COPpO2qBHDxJUu&limit=2&offset=0";

    ArrayList<Tumblr> tumblrs = new ArrayList<Tumblr>();
    return tumblrs;
}

private class GetChicks extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... unused) {
        // TODO Auto-generated method stub


                HttpClient client = new DefaultHttpClient();
                HttpGet get = new HttpGet(searchUrl);

                HttpResponse r = null;
                try {
                    r = client.execute(get);
                    int status = r.getStatusLine().getStatusCode();
                    if (status == 200) {
                        e = r.getEntity();
                        responseBody = EntityUtils.toString(e);
                    }
                } catch (ClientProtocolException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                JSONObject jsonObject;
                try {
                    jsonObject = new JSONObject(responseBody);

                    JSONArray posts = jsonObject.getJSONObject("response")
                            .getJSONArray("posts");

                    for (int i = 0; i < posts.length(); i++) {
                        JSONArray photos = posts.getJSONObject(i)
                                .getJSONArray("photos");
                        for (int j = 0; j < photos.length(); j++) {
                            JSONObject photo = photos.getJSONObject(j);
                            String url = photo.getJSONArray("alt_sizes")
                                    .getJSONObject(0).getString("url");

                            Tumblr tumblr = new Tumblr(url);
                            tumblrs.add(tumblr);

                        }
                    }

                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }



        return null;
    }

}

public class Tumblr {

    public String image_url;

    public Tumblr(String url) {

        this.image_url = url;

    }
}

private class loadMoreListView extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        // Showing progress dialog before sending http request
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("More chicks coming up..");
        pDialog.setIndeterminate(true);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    @Override
    protected Void doInBackground(Void... unused) {
        // TODO Auto-generated method stub

                // increment current page
                offset += 2;

                // Next page request
                tumblrs.clear();
                String searchUrl = "http://api.tumblr.com/v2/blog/factsandchicks.com/posts?api_key=rTZsymOWtMudbb5tql2U20qQ5ooYLPYVNnL3COPpO2qBHDxJUu&limit=2&offset="
                        + offset;

                HttpClient client = new DefaultHttpClient();
                HttpGet get = new HttpGet(searchUrl);

                HttpResponse r = null;
                try {
                    r = client.execute(get);
                    int status = r.getStatusLine().getStatusCode();
                    if (status == 200) {
                        HttpEntity e = r.getEntity();
                        responseBody = EntityUtils.toString(e);
                    }
                } catch (ClientProtocolException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                JSONObject jsonObject;
                try {
                    jsonObject = new JSONObject(responseBody);

                    JSONArray posts = jsonObject.getJSONObject("response")
                            .getJSONArray("posts");

                    for (int i = 0; i < posts.length(); i++) {
                        JSONArray photos = posts.getJSONObject(i)
                                .getJSONArray("photos");
                        for (int j = 0; j < photos.length(); j++) {
                            JSONObject photo = photos.getJSONObject(j);
                            String url = photo.getJSONArray("alt_sizes")
                                    .getJSONObject(0).getString("url");

                            Tumblr tumblr = new Tumblr(url);
                            tumblrs.add(tumblr);

                        }
                    }

                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                // Setting new scroll position
                listView.setSelectionFromTop(0, 0);



        return null;
    }

    protected void onPostExecute(Void unused) {
        pDialog.dismiss();

    }

}

@Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
    // TODO Auto-generated method stub
    super.onCreateOptionsMenu(menu);
    MenuInflater blowUp = getMenuInflater();
    blowUp.inflate(R.menu.cool_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    switch (item.getItemId()) {
    case R.id.aboutUs:
        Intent i = new Intent("com.example.example.ABOUT");
        startActivity(i);

        break;
    case R.id.refresh:
        Intent f = new Intent(MainActivity.this, MainActivity.class);
        startActivity(f);
        finish();
        break;
    case R.id.exit:
        finish();
        break;
    }
    return false;
}

}

日志如下所示:

 10-07 10:27:56.163: E/AndroidRuntime(923): FATAL EXCEPTION: AsyncTask #2
 10-07 10:27:56.163: E/AndroidRuntime(923): java.lang.RuntimeException: An error  occured while executing doInBackground()
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at  java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at  java.util.concurrent.FutureTask.run(FutureTask.java:137)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at  java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at java.lang.Thread.run(Thread.java:856)
 10-07 10:27:56.163: E/AndroidRuntime(923): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that  created a view hierarchy can touch its views.
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:3939)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:701)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.view.View.requestLayout(View.java:12555)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.view.View.requestLayout(View.java:12555)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.view.View.requestLayout(View.java:12555)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.view.View.requestLayout(View.java:12555)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.view.View.requestLayout(View.java:12555)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.widget.AbsListView.requestLayout(AbsListView.java:1690)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.widget.ListView.setSelectionFromTop(ListView.java:1928)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at com.fansheroid.facts.chicks.MainActivity$loadMoreListView.doInBackground(MainActivity.java:291)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at com.fansheroid.facts.chicks.MainActivity$loadMoreListView.doInBackground(MainActivity.java:1)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
 10-07 10:27:56.163: E/AndroidRuntime(923):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
 10-07 10:27:56.163: E/AndroidRuntime(923):     ... 5 more
4

1 回答 1

5

runOnUiThread()在用于在另一个线程中运行事物时调用方法,AsyncTask以避免在doInBackground()方法中为长进程拦截 UI 线程。我相信删除runOnUiThread()会完成这项工作。

于 2012-10-07T09:41:30.940 回答