2012-02-20 10 views
1

アンドロイドで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()メソッドは、クエリを作成して結果を返します。

ありがとうございます。

編集:

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

問題はAsyncTask内ではなく、国のテーブルの5行目にあります。 –

答えて

6

はあなたがNon-UIスレッドからUpdateにあなたのUIをいくつかのものをやっているようだ:ここでlogCatです。だから、UIを更新するためにあなたのものを入れてくださいrunOnUiThread()そのようにUIの踏み台自体のものを実行するように。

UPDATE:

だけonPreExecute()CheckCountryPresence();を取得するために自分のものを入れてみてください。だからあなたの編集したクラスでは、あなたはとてもこのような​​AsyncTaskのパラメータを全てボイドは、このprotected Void doInBackground(Void... voids)doInBackgroundを変更しますあなたのAsyncTaskの何かを渡していません

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を更新していません。私は自分のローカルデータベースのクエリを使って作業しており、上のコードで示されているいくつかの操作を行っています。 –

+1

あなたの質問にlogcat(エラー)を追加して、より良いアイデアを得るべきです。 –

+0

私はそれを加えて、私は私の質問を編集しました。 –

2

、のようにする必要があります。また、あなたはそれを使用していないので、onPreExecuteメソッドを取り除く。

また、提供されるコードが不明ですが、CheckIfUserIsLogedInをUIスレッドから呼び出す必要があります。 AsyncTaskは実際にUIスレッドから実行されることを意味しています。

+0

@ koopaking3ありがとう、でもまだsqme問題。 –

+0

コードのこの部分で何をしているのかというと、おそらく 'CountryTable country = new CountryTable();と' country.EnterCountry(); 'の問題です。彼らはおそらく、AsyncTaskが入っているアクティビティの外で何かをしようとしているでしょう。 – koopaking3

+0

'country.EnterCountry();'はいくつかのデータを返し、 'onPostExecute'でUIを更新するために使うことができます...正確に何をしているのかは分かりませんが、これは簡単な解決策。 – koopaking3

3

CountryTableクラスにUIアクティビティ/クラスとのやり取りはありますか?あなたのアダプタオブジェクトの新しい行を取得することさえできますか? 「はい」の場合、アクティビティーの外部からアクティビティーを更新することはできません。

あなたが解決策を見つけ出すたら幸いあなたはかなり簡単にこれを克服することができます;)

ステップ1:

onCheckCountryFinished(String taskResult)という単一のメソッドを持つCheckCountryCallbackのように、インターフェイスを定義します。

手順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(); 
     } 
    } 
}; 

コールバック例Iが直面問題の

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

simpleCursorAdapterthreadから呼び出さ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. 
} 
}); 
関連する問題