android.view.ViewRoot $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。

时间:2011-10-29 06:42:13

标签: android progressdialog

我正在开发一个Android应用程序,我需要在从服务器下载后显示图像,当下载正在进行时,正在显示进度对话框。为此我使用asynctask类。 我正在使用它的源代码。

           private void startDownload() {

    new DownloadFileAsync().execute(imageUrl);
    image.setImageBitmap(bitmap);
}
 @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_DOWNLOAD_PROGRESS:
                dialog = new ProgressDialog(this);
                dialog.setTitle("Loading");
                dialog.setMessage("Please wait...");
                dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                dialog.setCancelable(false);
                dialog.show();
                return dialog;
            default:
                return null;
        }
    }


 class DownloadFileAsync extends AsyncTask<String, String, String> {
     int count;
     URL myFileUrl;

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

        @Override
        protected String doInBackground(String... aurl) {


            try {
                myFileUrl = new URL(imageUrl);
                HttpURLConnection conn = (HttpURLConnection) myFileUrl
                        .openConnection();
                int lenghtOfFile = conn.getContentLength();
                //conn.setDoInput(true);
                conn.setConnectTimeout(10000);
                conn.setReadTimeout(10000);
                conn.connect();
                InputStream is = conn.getInputStream();
                bmImg = BitmapFactory.decodeStream(is);
                bitmap = BitmapFactory.decodeStream((InputStream) new URL(imageUrl)
                        .getContent());
                bitmap = Bitmap.createScaledBitmap(bitmap, 70, 70, true);

                  byte data[] = new byte[1024];
                  System.out.println("mmmmmmmmmmmm");

                    long total = 0;
                    System.out.println("nnnnnnnnnn");
                    while ((count = ((InputStream) new URL(imageUrl)
                    .getContent()).read(data)) != -1) {
                        total += count;
                        publishProgress(""+(int)((total*100)/lenghtOfFile));
                        for(int l=0;l<4;l++){
                        if(listObject.get(l).getImage()!="")
                       image.setImageBitmap(bitmap);
                    }}

            }
            catch(Exception e){
                System.out.println(e);}

        return null;
        }

        protected void onProgressUpdate(String... progress) {
            dialog.setProgress(Integer.parseInt(progress[0]));
        }

        @Override
        protected void onPostExecute(String unused) {
            image.setImageBitmap(bitmap);
            dismissDialog(DIALOG_DOWNLOAD_PROGRESS);

        }
        }

但是它给出了以下例外。:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

我无法弄清楚问题所在。任何人都可以帮助我。 感谢

1 个答案:

答案 0 :(得分:5)

这是你的问题:

for(int l=0;l<4;l++){
    if(listObject.get(l).getImage()!="")
        image.setImageBitmap(bitmap);
}

简短的回答:就像异常所说的那样,你试图在错误的线程中操纵一个视图。在正确的线程(UI线程)中执行。

答案很长:在AsyncTask中,进行视图操作的正确位置通常是onPreExecuteonProgressUpdateonPostExecutedoInBackground通常不是修改视图的好地方。您可以通过多种方式之一 回调UI线程(例如,您可以使用post)。但是,您发布的那段代码对我来说并不是很有意义,而且您没有展示足够的上下文来解释它是什么,listObject是什么等等。

你也有其他一些问题。您似乎试图以两种不同的方式连续两次读取数据...此外,我想您的while条件会在您重新创建URL对象时给您带来问题,只要你收到内容,你会继续这样做。假设URL没有动态内容,您将拥有无限循环。