2012-02-20 53 views
1

我想在android上使用AsyncTask類,但我有一個問題。不能在線程中創建處理程序沒有調用與AsyncTask Looper.prepare()

這裏是我的代碼:

public void CheckIfUserIsLogedIn() 
{ 
    int userPresence = localDatabase.CheckUserPresence(); 
    if (userPresence == 0) 
    { 
     setContentView(R.layout.main); 
     new checkCountryAsync().execute(); 
    } 
    else 
    { 
     setContentView(R.layout.userlogedon); 
    } 
} 

class checkCountryAsync extends AsyncTask<String, String, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 
    @Override 
    protected String doInBackground(String... aurl) { 
     int countryPresence = localDatabase.CheckCountryPresence(); 
     if (countryPresence == 0) 
     { 
      CountryTable country = new CountryTable() ; 
      country.EnterCountry(); 
     } 
     return null; 
    } 
} 

我不知道我做錯了什麼。 LocalDatabase類中的CheckCountryPresence()方法只進行查詢並返回結果。

謝謝。

編輯:這裏是logcat的:

02-20 08:41:25.804: W/dalvikvm(26458): threadid=10: thread exiting with uncaught exception (group=0x4001d5a0) 
02-20 08:41:25.834: E/AndroidRuntime(26458): FATAL EXCEPTION: AsyncTask #1 
02-20 08:41:25.834: E/AndroidRuntime(26458): java.lang.RuntimeException: An error occured while executing doInBackground() 
02-20 08:41:25.834: E/AndroidRuntime(26458): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at java.lang.Thread.run(Thread.java:1027) 
02-20 08:41:25.834: E/AndroidRuntime(26458): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
02-20 08:41:25.834: E/AndroidRuntime(26458): at android.os.Handler.<init>(Handler.java:121) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at android.app.Activity.<init>(Activity.java:717) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at milos.mdpi.CountryTable.<init>(CountryTable.java:5) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at milos.mdpi.MDPIActivity$checkCountryAsync.doInBackground(MDPIActivity.java:367) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at milos.mdpi.MDPIActivity$checkCountryAsync.doInBackground(MDPIActivity.java:1) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at android.os.AsyncTask$2.call(AsyncTask.java:185) 
02-20 08:41:25.834: E/AndroidRuntime(26458): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
02-20 08:41:25.834: E/AndroidRuntime(26458): ... 4 more 
+0

在我看來問題是在國家表的第5行,而不是在AsyncTask! – 2012-02-20 08:16:33

回答

6

看來你是從Non-UI線程做一些東西Update你的UI。所以,你應該把自己的東西更新到runOnUiThread()裏面,這樣它就可以執行你自己UI上的東西。

UPDATE:

就儘量把你的東西用於獲取CheckCountryPresence();onPreExecute()。所以,你的編輯類應該是這樣的,

class checkCountryAsync extends AsyncTask<String, String, String> { 

    int countryPresence = 0; 
    @Override 
    protected void onPreExecute() { 
     countryPresence = localDatabase.CheckCountryPresence(); 
    } 
    @Override 
    protected String doInBackground(String... aurl) { 

     Activity_name.this.runOnUiThread(new Runnable() { 

     @Override 
     public void run() { 
      if (countryPresence == 0) 
      { 
       CountryTable country = new CountryTable() ; 
       country.EnterCountry(); 
      } 
     } 
    }); 
     return null; 
    } 
} 
+0

謝謝@Lalit,但我沒有從AsyncTask更新我的UI。我只使用本地數據庫上的查詢,並在上面的代碼中顯示了一些操作。 – 2012-02-20 07:32:48

+1

你應該添加logcat(錯誤)與你的問題,以獲得更好的主意。 – 2012-02-20 07:33:50

+0

我加了,我編輯了我的問題。 – 2012-02-20 07:43:16

2

你是不是通過你的AsyncTask過這麼使的AsyncTask的參數,這樣​​所有太虛然後更改doInBackground這個protected Void doInBackground(Void... voids)。此外,擺脫onPreExecute方法,因爲你甚至沒有使用它。

此外,您提供的代碼還不清楚,但需要從UI線程調用CheckIfUserIsLogedIn。 AsyncTask實際上只是意味着從UI線程運行。

+0

謝謝@ koopaking3但仍然是sqme問題。 – 2012-02-20 07:39:27

+0

可能是你在這部分代碼中做了什麼的問題,然後是'CountryTable country = new CountryTable();'和'country.EnterCountry();'。他們可能正在嘗試在AsyncTask所在的Activity之外做些什麼。也許還會發布這些代碼,或向我們描述它們的功能? – koopaking3 2012-02-20 07:47:11

+0

你可以讓'country.EnterCountry();'返回一些數據並使用它來更新'onPostExecute'中的用戶界面...很難說,因爲它不清楚它們究竟做了什麼,但這將是一個簡單的解決方案。 – koopaking3 2012-02-20 07:52:31

3

您的CountryTable類是否與UI活動/類有任何交互?甚至爲適配器對象獲取新行? 如果是,則不能從活動本身之外更新活動。

幸運可以克服這個很容易地一旦你找出溶液)

步驟1:

定義的接口,像CheckCountryCallback使用單個方法調用onCheckCountryFinished(String taskResult);

步驟2:讓調用你的asynctask的活動實現這個接口及其方法。

步驟3:定義您的AsyncTask構造類型的單個參數CheckCountryCallback

步驟4:覆蓋你的AT onPostExecute,和簡單的寫mCaller.onCheckCountryFinished(結果)。

這還不夠,因爲你仍然會從另一個線程更新ui,但我們正在接近!

在您實施的onCheckCountryFinished中,您應該將呼叫重定向到您必須在活動中定義的處理程序。向該處理程序發送消息,並且可以從處理程序的句柄消息方法更新UI(或適配器或其他)。

處理程序例如:

private static final int UPDATE = 2; 
private Handler handler = new Handler() { 

    public void handleMessage(Message msg) { 
     if (msg.what == UPDATE) { 
       //do something with m.obj 
       myAdapter.notifyDataSetChanged(); 
     } 
    } 
}; 

回調例如

public void onCheckCountryFinished(String result){ 
    Message m = Message.obtain(); 
    m.what = UPDATE; 
    m.obj = result; 
    handler.sendMessage(m); 
} 
1

,我所面臨的問題之一,simpleCursorAdapter也返回從thread調用時的looper同樣的錯誤。所以要消除該錯誤,內線程

ActivityName.this.runOnUiThread(new Runnable() { 
public void run() { 
    String[] FROM = {/*your data here*/}; 
int[] TO = { /*your data here*/ }; 
adapter = new SimpleCursorAdapter(ActivityName.this, R.layout.row, cursor, FROM, TO); 
listTimeline.setAdapter(adapter); //your own code here. 
} 
}); 
相關問題