2012-09-06 78 views
0

我使用Google圖表API在我的應用程序中構建圖表。AsyncTask下載圖片錯誤

在我的情況下,我需要下載每個圖表上的圖像。我爲此使用AsyncTask。

要監視下載過程,我使用進度對話框。但是在這個AsyncTask類中出現錯誤。

執行的AsyncTask的:

new loadChart(ChartAct.this,img).execute(); 

和的AsyncTask代碼:

public class loadChart extends AsyncTask<Void, Void, Void> { 
    private ImageView img; 
    private Context con; 
    private ProgressDialog dialog; 

    public loadChart(Context context, ImageView img1) { 
     this.img = img1; 
     this.con = context; 
    } 

    @Override 
    protected void onPreExecute() { 
     dialog = ProgressDialog.show(con, "Connecting:", 
       "Loading. Please wait...", true); 
     super.onPreExecute(); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     final Bitmap bitmap = DownloadImage(); 
     img.setImageBitmap(bitmap); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     dialog.dismiss(); 
     super.onPostExecute(result); 
    } 

    private static InputStream OpenHttpConnection(String urlString) 
      throws IOException { 

     Log.d("palval", "OpenHttpConnection"); 
     InputStream in = null; 
     int response = -1; 

     URL url = new URL(urlString); 
     URLConnection conn = url.openConnection(); 

     if (!(conn instanceof HttpURLConnection)) 
      throw new IOException("Not an HTTP connection"); 

     try { 
      HttpURLConnection httpConn = (HttpURLConnection) conn; 
      httpConn.setAllowUserInteraction(false); 
      httpConn.setInstanceFollowRedirects(true); 
      httpConn.setRequestMethod("GET"); 
      httpConn.connect(); 

      response = httpConn.getResponseCode(); 

      if (response == HttpURLConnection.HTTP_OK) { 
       in = httpConn.getInputStream(); 
      } 

      String res = Integer.toString(response); 
     } catch (Exception ex) { 
      throw new IOException("Error connecting"); 
     } 
     return in; 
    } 

    public static Bitmap DownloadImage() { 
     Log.d("palval", "DownloadImage"); 
     Bitmap bitmap = null; 
     InputStream in = null; 
     try { 

      in = OpenHttpConnection("https://chart.googleapis.com/chart?chs=440x220&chd=t:60,40&cht=p3&chl=Hello|World"); 
      bitmap = BitmapFactory.decodeStream(in); 
      in.close(); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
     return bitmap; 
    } 

} 

錯誤:

09-06 18:35:35.574: E/AndroidRuntime(2502): FATAL EXCEPTION: AsyncTask #1 
09-06 18:35:35.574: E/AndroidRuntime(2502): java.lang.RuntimeException: An error occured while executing doInBackground() 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.os.AsyncTask$3.done(AsyncTask.java:278) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at java.lang.Thread.run(Thread.java:864) 
09-06 18:35:35.574: E/AndroidRuntime(2502): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4132) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:723) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.view.View.requestLayout(View.java:12957) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.view.View.requestLayout(View.java:12957) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.view.View.requestLayout(View.java:12957) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.view.View.requestLayout(View.java:12957) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.view.View.requestLayout(View.java:12957) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.widget.ImageView.setImageDrawable(ImageView.java:362) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.widget.ImageView.setImageBitmap(ImageView.java:377) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at com.example.headache.loadChart.doInBackground(loadChart.java:37) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at com.example.headache.loadChart.doInBackground(loadChart.java:1) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at android.os.AsyncTask$2.call(AsyncTask.java:264) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
09-06 18:35:35.574: E/AndroidRuntime(2502):  ... 5 more 
09-06 18:35:36.055: E/WindowManager(2502): Activity com.example.headache.ChartAct has leaked window [email protected] that was originally added here 
09-06 18:35:36.055: E/WindowManager(2502): android.view.WindowLeaked: Activity com.example.headache.ChartAct has leaked window [email protected] that was originally added here 
09-06 18:35:36.055: E/WindowManager(2502): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:352) 
09-06 18:35:36.055: E/WindowManager(2502): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:373) 
09-06 18:35:36.055: E/WindowManager(2502): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:321) 
09-06 18:35:36.055: E/WindowManager(2502): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152) 
09-06 18:35:36.055: E/WindowManager(2502): at android.view.Window$LocalWindowManager.addView(Window.java:541) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.Dialog.show(Dialog.java:301) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.ProgressDialog.show(ProgressDialog.java:116) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.ProgressDialog.show(ProgressDialog.java:99) 
09-06 18:35:36.055: E/WindowManager(2502): at com.example.headache.loadChart.onPreExecute(loadChart.java:29) 
09-06 18:35:36.055: E/WindowManager(2502): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:561) 
09-06 18:35:36.055: E/WindowManager(2502): at android.os.AsyncTask.execute(AsyncTask.java:511) 
09-06 18:35:36.055: E/WindowManager(2502): at com.example.headache.ChartAct.onCreate(ChartAct.java:31) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.Activity.performCreate(Activity.java:4531) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2150) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2229) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.ActivityThread.access$600(ActivityThread.java:139) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261) 
09-06 18:35:36.055: E/WindowManager(2502): at android.os.Handler.dispatchMessage(Handler.java:99) 
09-06 18:35:36.055: E/WindowManager(2502): at android.os.Looper.loop(Looper.java:154) 
09-06 18:35:36.055: E/WindowManager(2502): at android.app.ActivityThread.main(ActivityThread.java:4945) 
09-06 18:35:36.055: E/WindowManager(2502): at java.lang.reflect.Method.invokeNative(Native Method) 
09-06 18:35:36.055: E/WindowManager(2502): at java.lang.reflect.Method.invoke(Method.java:511) 
09-06 18:35:36.055: E/WindowManager(2502): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
09-06 18:35:36.055: E/WindowManager(2502): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
09-06 18:35:36.055: E/WindowManager(2502): at dalvik.system.NativeStart.main(Native Method) 

回答

1

您不能設置在doInBackground()圖像使其返回一個位圖,並將其設置在onPostExecute()

public class loadChart extends AsyncTask<Void, Void, Bitmap> { 
    private ImageView img; 
    private Context con; 
    private ProgressDialog dialog; 

    public loadChart(Context context, ImageView img1) { 
     this.img = img1; 
     this.con = context; 
    } 

    @Override 
    protected void onPreExecute() { 
     dialog = ProgressDialog.show(con, "Connecting:", 
       "Loading. Please wait...", true); 
     super.onPreExecute(); 
    } 

    @Override 
    protected Bitmap doInBackground(Void... params) { 
     final Bitmap bitmap = DownloadImage(); 
     return bitmap; 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     dialog.dismiss(); 
     img.setImageBitmap(result); 
    } 
0

不能從doInBackground()訪問UI,這是你通過設置做什麼與您的img.setImageBitmap(bitmap);位圖。如果您在使用runOnUiThread()進行背景活動時需要這樣做,請將您的UI訪問代碼移至onPostExecute(),即將對象中的位圖存儲,但將其分配給onProgressUpdate()中的UI元素。一般來看看AsyncTask documentation

+0

我能做到這一點的postExecute? – Val

+0

是的,您應該在'doInBackground()'中返回您的位圖,並將其設置在'onPostExecute()' – tolgap

+0

@ p.Valery中。請參閱編輯答案 –

0

您無法從doInBackground()修改UI元素。

嘗試使用您的活動的方法runOnUIThread()或將UI更改爲onPostExecute()方法的方法。

閱讀this answer瞭解更多詳情。