0

我試圖做多線程,但我已經有了一些智能手機這個堆棧跟蹤(SGS2):multitreading UI:的ExceptionInInitializerError和運行時異常的Android

java.lang.ExceptionInInitializerError 
at com.android.bordeaux.code.model.AnnouncersContainer.setLoudArrayFromJSON_online(AnnouncersContainer.java:68) 
at com.android.bordeaux.code.SplashscreenActivity_Second$1.run(SplashscreenActivity_Second.java:55) 
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
at android.os.Handler.<init>(Handler.java:121) 
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421) 
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421) 
at android.os.AsyncTask.<clinit>(AsyncTask.java:152) 
... 2 more 

這是我的主要活動(閃屏)至極正在爲了幾秒鐘內觀望等待我的AsyncTask完成:

public class SplashscreenActivity_Second extends Activity 
     {  
      @Override 
      public void onCreate(Bundle savedInstanceState) 
      { 
       super.onCreate(savedInstanceState); 
       setContentView(R.layout.splashscreen_second); 

       // thread 
       Thread splashThread = new Thread() 
       { 
        @Override 
        public void run() 
        { 
         try 
         { 
          int waited = 0; 

          if (isInternetOn()) 
          { 
// Here I'm making my asynctask !! 
AnnouncersContainer.setLoudArrayFromJSON_online(getApplicationContext()); 
           while (waited < 5000) 
           { 
            sleep(50); 
            waited += 40; 
           } 
          } 
          else 
          {      
           AnnouncersContainer.setLoudArrayFromXML_local(getApplicationContext()); 
           while(waited < 5000) 
           { 
            sleep(50); 
            waited += 60; 
           } 
          } 
         } 
         catch(InterruptedException e) 
         { 
          e.printStackTrace(); 
         } 
         finally 
         { 
          Intent intent_to_tabhost = new Intent(SplashscreenActivity_Second.this, MyTabActivity.class); 
          startActivity(intent_to_tabhost); 
          finish(); 
         } 
        } 
       }; 
       splashThread.start(); 
      } 
} 

這裏是我的AsyncTask:

public class DownloadAnnouncers extends AsyncTask<Void, Integer, Boolean> 
{ 
    public static Boolean loadFinished = false; 

    //JSON variables.. 


    private static String url = null; 

    Context context; 

    public DownloadAnnouncers(Context context) 
    { 
     this.context = context; 
    } 

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

    protected Boolean doInBackground(Void... params) 
    { 

    // fine retrieving all my JSON data in a global array.. 

    } 

    @Override 
    protected void onPostExecute(Boolean downloadedArray) 
    { 
     super.onPostExecute(downloadedArray); 
    } 
} 

我知道問題是我在UI中進行多線程,但有人可以告訴我如何刪除我的循環線程,並用我的Asynctask的onPostExecute()方法替換它? (它可能是最好等待的AsyncTask完成,而不是讓等待..)

或可能是幫我糾正與多線程這個錯誤..

編輯:

我的AsyncTask:

public class DownloadAnnouncers extends AsyncTask<Void, Integer, Boolean> 
    { 
     public static Boolean loadFinished = false; 

     //JSON variables.. 


     private static String url = null; 

     Context context; 

     public DownloadAnnouncers(Context context) 
     { 
      this.context = context; 
     } 

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

     protected Boolean doInBackground(Void... params) 
     { 

     // fine retrieving all my JSON data in a global array.. 

     } 

     @Override 
     protected void onPostExecute(Boolean downloadedArray) 
     { 
      super.onPostExecute(downloadedArray); 
     Intent intent_to_tabhost = new Intent(context, MyTabActivity.class); 
     intent_to_tabhost.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(intent_to_tabhost); 
     } 
    } 

但現在如果我按取消鍵,我回到我的啓動畫面活動..我做不到ctx.finish()在onPostExecute方法..

回答

1

呦你無法創建一個Handler已經不叫Looper.prepare(),就像你的錯誤消息指出線程內:

不能()內螺紋已不叫Looper.prepare創建處理程序

處理程序在AsyncTask內創建,因此它不是您一開始可能會看到的。

如果你想保留你的代碼,你可以通過將AsyncTask的創建移動到你的自定義線程之外來解決它。

但是,您不需要創建線程,只需在ui線程中創建AsyncTask(它將運行在它自己的線程中,這樣它就不會在工作時鎖定手機),並執行任何操作在onPostExecute-方法中完成任務後所需執行的操作。

class ExampleAsync extends AsyncTask<Void, Integer, Boolean> 
{ 
    public static Boolean loadFinished = false; 
    //JSON variables.. 
    private static String url = null; 
    Context context; 

    public DownloadAnnouncers(Context context){ 
     this.context = context; 
    } 

    protected Boolean doInBackground(Void... params){ 
     // fine retrieving all my JSON data in a global array.. 
    } 

    @Override 
    protected void onPostExecute(Boolean downloadedArray){ 
     Intent intent_to_tabhost = new Intent(context, MyTabActivity.class); 
     startActivity(intent_to_tabhost); 
    } 
} 

而在你的活動:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.splashscreen_second); 
    AsyncTask myTask = new ExampleAsync(this); 
    myTask.execute(); 
} 
0

而不是等待的AsyncTask,使用onPostExecute,這就是所謂的任務完成後,纔在UI線程上。

如果活動已被破壞(例如,用戶在顯示啓動畫面時按下後退按鈕),您也應取消該任務。

+0

最後它的工作原理,我不得不將asynctask添加到我的splashscreen活動中(asynctask wasnt內部之前),所以我可以調用finish() – eento 2013-02-10 14:40:05