加载更多 - 只有创建视图层次可以触摸其观点原来的线程 [英] Load More - Only the original thread that created a view hierarchy can touch its views

查看:190
本文介绍了加载更多 - 只有创建视图层次可以触摸其观点原来的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序正在使用的GridView从JSON获取图像。一切都OK了,但现在我希望把它通过点击按钮加载更多。我跟着这个教程的Andr​​oid的ListView与负载更多按钮
当我跟着它,我用 runOnUiThread(新的Runnable(){
                公共无效的run(){}}
doInBackground ,但它的错误 NetworkOnMainThreadException 我知道这个因为我在UI线程中运行它。但是当我删除 runOnUiThread ... ,其错误也

如何解决这个问题?完整的源 http://pastie.org/5659969

  01-10 14:39:14.970:E / AndroidRuntime(19609):致命异常:AsyncTask的#3
01-10 14:39:14.970:E / AndroidRuntime(19609):了java.lang.RuntimeException:执行doInBackground发生错误()
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.os.AsyncTask $ 3.done(AsyncTask.java:299)
01-10 14:39:14.970:E / AndroidRuntime(19609):在java.util.concurrent.FutureTask中$ Sync.innerSetException(FutureTask.java:273)
01-10 14:39:14.970:E / AndroidRuntime(19609):在java.util.concurrent.FutureTask.setException(FutureTask.java:124)
01-10 14:39:14.970:E / AndroidRuntime(19609):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:307)
01-10 14:39:14.970:E / AndroidRuntime(19609):在java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:230)
01-10 14:39:14.970:E / AndroidRuntime(19609):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-10 14:39:14.970:E / AndroidRuntime(19609):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
01-10 14:39:14.970:E / AndroidRuntime(19609):在java.lang.Thread.run(Thread.java:856)
01-10 14:39:14.970:E / AndroidRuntime(19609):$ android.view.ViewRootImpl CalledFromWrongThreadException:只有创建视图层次可以触摸其观点原来的线程所致。
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4847)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:974)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.view.ViewGroup.invalidateChild(ViewGroup.java:4075)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.view.View.invalidate(View.java:10525)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.view.View.invalidate(View.java:10480)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.widget.ImageView.invalidateDrawable(ImageView.java:190)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:350)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.graphics.drawable.Drawable.setVisible(Drawable.java:546)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.widget.ImageView.onDetachedFromWindow(ImageView.java:1173)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.view.View.dispatchDetachedFromWindow(View.java:12096)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2541)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:3828)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.widget.AbsListView.resetList(AbsListView.java:2130)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.widget.GridView.setAdapter(GridView.java:170)
01-10 14:39:14.970:E / AndroidRuntime(19609):在com.camitss.mcolle.CardActivity $ LoadMore.doInBackground(CardActivity.java:254)
01-10 14:39:14.970:E / AndroidRuntime(19609):在com.camitss.mcolle.CardActivity $ LoadMore.doInBackground(CardActivity.java:1)
01-10 14:39:14.970:E / AndroidRuntime(19609):在android.os.AsyncTask $ 2.call(AsyncTask.java:287)
01-10 14:39:14.970:E / AndroidRuntime(19609):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
01-10 14:39:14.970:E / AndroidRuntime(19609):... 5个

AsyncTask的时候第一次加载

  //下载JSON的背景
公共类DownloadJSONFileAsync扩展的AsyncTask<弦乐,太虚,太虚> {
    。字符串标记= getIntent()getExtras()的getString(TOKEN1);    在preExecute保护无效(){
        super.on preExecute();
        的ShowDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
    }    @覆盖
    保护无效doInBackground(字符串... PARAMS){
        字符串URL =htt​​p://xxx.xxx.xxx/card/all/\"+num_page+\"/0/?token=\"+token;
        JSONArray数据= NULL;        尝试{            的JSONObject的JSONObject =新的JSONObject(getJSONUrl(URL));
            MyArrList =新的ArrayList<&HashMap的LT;弦乐,对象>>();
            HashMap的<弦乐,对象>地图;
            数据= jsonObject.getJSONArray(数据);            的for(int i = 0; I< data.length();我++){
                JSONObject的C = data.getJSONObject(I)
                地图=新的HashMap<弦乐,对象>();                //缩略图获取ImageBitmap到对象
                map.put(cardimage(字符串)c.getString(cardimage));
                map.put(ImageThumBitmap,(位图)loadBitmap(c.getString(cardimage)));
                map.put(类别ID(字符串)c.getString(类别ID));
                MyArrList.add(地图);
            }        }赶上(JSONException E){
            // TODO自动生成catch块
            e.printStackTrace();
        }        返回null;
    }    保护无效onPostExecute(虚空未使用){
        ShowAllContent(); //当完成显示内容
        dismissDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
        removeDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
    }}

AsycTask使用按钮,点击加载更多的时候

  //装载更多公共类LoadMore扩展的AsyncTask<弦乐,太虚,太虚> {    。字符串标记= getIntent()getExtras()的getString(TOKEN1);    在preExecute保护无效(){
        super.on preExecute();
        的ShowDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
    }    @覆盖
    保护无效doInBackground(字符串... PARAMS){
                num_page + = 1;
                字符串URL =htt​​p://xxx.xxx.xxx/card/all/\"+num_page+\"/0/?token=\"+token;
                JSONArray数据= NULL;                尝试{                    的JSONObject的JSONObject =新的JSONObject(getJSONUrl(URL));                    MyArrList =新的ArrayList<&HashMap的LT;弦乐,对象>>();
                    HashMap的<弦乐,对象>地图;
                    数据= jsonObject.getJSONArray(数据);
                    的for(int i = 0; I< data.length();我++){
                        JSONObject的C = data.getJSONObject(I)
                        地图=新的HashMap<弦乐,对象>();                        //缩略图获取ImageBitmap到对象
                        map.put(cardimage(字符串)c.getString(cardimage));
                        map.put(ImageThumBitmap,(位图)loadBitmap(c.getString(cardimage)));
                        map.put(类别ID(字符串)c.getString(类别ID));
                        MyArrList.add(地图);
                    }                    INT currentPosition = gridView1.getFirstVisiblePosition();
                    ImageAdapter适配器=新ImageAdapter(CardActivity.this,MyArrList);
                    gridView1.setAdapter(适配器);
                    gridView1.setSelection(currentPosition + 1);                }赶上(JSONException E){
                    // TODO自动生成catch块
                    e.printStackTrace();
                }
        返回null;
    }    保护无效onPostExecute(虚空未使用){
        ShowAllContent();
        dismissDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
        removeDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
    }}


解决方案

您也许应该提出这个code:

  INT currentPosition = gridView1.getFirstVisiblePosition();
                ImageAdapter适配器=新ImageAdapter(CardActivity.this,MyArrList);
                gridView1.setAdapter(适配器);
                gridView1.setSelection(currentPosition + 1);

onPostExecute 方法,因为它必须在UI线程上运行

My app is using GridView to get image from JSON. Everything is ok but now I want to make it for loading more by clicking on button. I followed this tutorial Android ListView with Load More Button. When I followed it, I used runOnUiThread(new Runnable() { public void run() { } } in the doInBackground but it errors NetworkOnMainThreadException i knew this cuz I run it on UI thread. but when I remove runOnUiThread..., it errors also

How can I fix this error? full source http://pastie.org/5659969

01-10 14:39:14.970: E/AndroidRuntime(19609): FATAL EXCEPTION: AsyncTask #3
01-10 14:39:14.970: E/AndroidRuntime(19609): java.lang.RuntimeException: An error occured while executing doInBackground()
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at java.lang.Thread.run(Thread.java:856)
01-10 14:39:14.970: E/AndroidRuntime(19609): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4847)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:974)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:4075)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.view.View.invalidate(View.java:10525)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.view.View.invalidate(View.java:10480)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.widget.ImageView.invalidateDrawable(ImageView.java:190)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:350)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.graphics.drawable.Drawable.setVisible(Drawable.java:546)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.widget.ImageView.onDetachedFromWindow(ImageView.java:1173)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.view.View.dispatchDetachedFromWindow(View.java:12096)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2541)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:3828)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.widget.AbsListView.resetList(AbsListView.java:2130)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.widget.GridView.setAdapter(GridView.java:170)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at com.camitss.mcolle.CardActivity$LoadMore.doInBackground(CardActivity.java:254)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at com.camitss.mcolle.CardActivity$LoadMore.doInBackground(CardActivity.java:1)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-10 14:39:14.970: E/AndroidRuntime(19609):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-10 14:39:14.970: E/AndroidRuntime(19609):    ... 5 more

AsyncTask when first load

// Download JSON in Background
public class DownloadJSONFileAsync extends AsyncTask<String, Void, Void> {
    String token = getIntent().getExtras().getString("token1");

    protected void onPreExecute() {
        super.onPreExecute();
        showDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
    }

    @Override
    protected Void doInBackground(String... params) {
        String url = "http://xxx.xxx.xxx/card/all/"+num_page+"/0/?token="+token;
        JSONArray data = null;

        try {

            JSONObject jsonObject = new JSONObject(getJSONUrl(url));
            MyArrList = new ArrayList<HashMap<String, Object>>();
            HashMap<String, Object> map;
            data = jsonObject.getJSONArray("data");

            for (int i = 0; i < data.length(); i++) {
                JSONObject c = data.getJSONObject(i);
                map = new HashMap<String, Object>();

                // Thumbnail Get ImageBitmap To Object
                map.put("cardimage", (String) c.getString("cardimage"));
                map.put("ImageThumBitmap",(Bitmap) loadBitmap(c.getString("cardimage")));
                map.put("categoryid", (String) c.getString("categoryid"));
                MyArrList.add(map);
            }

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

        return null;
    }

    protected void onPostExecute(Void unused) {
        ShowAllContent(); // When Finish Show Content
        dismissDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
        removeDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
    }

}

AsycTask when using button to click to load more

// load more

public class LoadMore extends AsyncTask<String, Void, Void> {

    String token = getIntent().getExtras().getString("token1");

    protected void onPreExecute() {
        super.onPreExecute();
        showDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
    }

    @Override
    protected Void doInBackground(String... params) {
                num_page += 1;
                String url = "http://xxx.xxx.xxx/card/all/"+num_page+"/0/?token="+token;
                JSONArray data = null;

                try {

                    JSONObject jsonObject = new JSONObject(getJSONUrl(url));

                    MyArrList = new ArrayList<HashMap<String, Object>>();
                    HashMap<String, Object> map;
                    data = jsonObject.getJSONArray("data");
                    for (int i = 0; i < data.length(); i++) {
                        JSONObject c = data.getJSONObject(i);
                        map = new HashMap<String, Object>();

                        // Thumbnail Get ImageBitmap To Object
                        map.put("cardimage", (String) c.getString("cardimage"));
                        map.put("ImageThumBitmap",(Bitmap) loadBitmap(c.getString("cardimage")));
                        map.put("categoryid", (String) c.getString("categoryid"));
                        MyArrList.add(map);
                    }

                    int currentPosition = gridView1.getFirstVisiblePosition();
                    ImageAdapter adapter = new ImageAdapter(CardActivity.this, MyArrList);
                    gridView1.setAdapter(adapter);
                    gridView1.setSelection(currentPosition + 1);

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

    protected void onPostExecute(Void unused) {
        ShowAllContent();
        dismissDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
        removeDialog(DIALOG_DOWNLOAD_JSON_PROGRESS);
    }

}

解决方案

You should probably move this code:

                int currentPosition = gridView1.getFirstVisiblePosition();
                ImageAdapter adapter = new ImageAdapter(CardActivity.this, MyArrList);
                gridView1.setAdapter(adapter);
                gridView1.setSelection(currentPosition + 1);

into the onPostExecute method, because it has to be run on UI thread

这篇关于加载更多 - 只有创建视图层次可以触摸其观点原来的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆