2012-03-15 6 views
3

私はバックグラウンドでdbクエリを実行するAsyncTaskを拡張するネストされた内部クラスを持っています。しかし、一部のユーザーが持っている - これは正常に動作時間のほとんどAsyncTaskのpostExecuteメソッドがUIスレッドで実行されないのはなぜですか?

private void onCursorLoaded(Cursor c) 
{ 
    mPagerAdapter = new LeadDetailsFragmentPagerAdaper(getSupportFragmentManager()); 
    mPager.setAdapter(mPagerAdapter); 
    mPager.setCurrentItem(iIndex, false); 
} 

:記事で私はこの

private class QueryRunner extends AsyncTask<Void,Void,Cursor> { 

    @Override 
    protected Cursor doInBackground(Void... voids) 
    { 
    return getContentResolver().query(LeadContentProvider.buildUri(app.getEntityId()),new String[]{LeadContentProvider._ID},null,null,LeadContentProvider.LEAD_STATUS_DATETIME +" desc"); 
    } 

    @Override 
    protected void onPostExecute(Cursor c) 
    { 
    onCursorLoaded(c); 
    } 
} 

のようなものがonCursorLoaded方法がどのように見えるのビューを更新するために、親のメソッドを呼び出していますメソッドを実行しますこのスタックトレースでクラッシュします。

java.lang.IllegalStateException: Must be called from main thread of process 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1392) 
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431) 
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139) 
at android.support.v4.view.ViewPager.populate(ViewPager.java:804) 
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:344) 
at com.servicemagic.pros.activities.LeadDetails.onCursorLoaded(LeadDetails.java:205) 
at com.servicemagic.pros.activities.LeadDetails.access$200(LeadDetails.java:25) 
at com.servicemagic.pros.activities.LeadDetails$QueryRunner.onPostExecute(LeadDetails.java:196) 
at com.servicemagic.pros.activities.LeadDetails$QueryRunner.onPostExecute(LeadDetails.java:170) 
at android.os.AsyncTask.finish(AsyncTask.java:417) 
at android.os.AsyncTask.access$300(AsyncTask.java:127) 
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:150) 
at android.os.HandlerThread.run(HandlerThread.java:60) 

- なぜ、mainExecute()メソッドがMainThreadで呼び出されないのですか?

+0

AsynkTaskを拡張する内部クラスをどのように定義しますか?コードを表示できますか? – hovanessyan

+0

トップコードブロックを完全なAsycTaskコードで更新します。 – harmanjd

+0

私は階層全体を意味します - 親クラス+内部クラス定義。親クラスはアクティビティですか? – hovanessyan

答えて

2

@hovanessyanが得ていることは、あなたのAsyncTaskが起動時に話していた断片が、実行が終了したときと同じでないかもしれないと仮定するのは安全ではないということです。 AsyncTaskが実行されている間、Androidはフラグメントを一時停止または終了することがあります。それはなぜ問題が断続的であるのかを説明します。ユーザーの断片が一時停止または破棄されて再作成された場合にのみ、ユーザーに発生します。

この問題は、in this articleについて説明しています。あなたが記事の項目2と3を読んだら、それに対処する方法がわかります。お客様は、フラグメントのライフサイクルの一環として州を保存および復元する責任があります。 Fragment lifecycleのアンドロイドのドキュメントを参照してください。

+0

記事へのリンクありがとうございます。私はおそらく今起こっていることをよく理解していると思うが、確かめるためにここに述べる。 onCreate()またはそれ以降でAsyncTaskを作成すると、アクティビティのライフサイクルが:onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy() onPause()を呼び出すと、再びonResume()が呼び出されるとメインスレッドになりますが、本来のアクティビティを作成するのに同じメインスレッドを使う必要はありません。 この場合、AsyncTaskが終了すると、onPostExecute()メソッドはこの動作を示すことがあります。 – harmanjd

+0

上記の記事のパターンを使用すると、アクティビティが一時停止されたときに、新しいスレッドコンテキストで実行されている時点でアクティビティが再開されるまでコールバックが発生しなくなるため、発生しません。それはあなたの理解ですか? – harmanjd

+0

はい、それは私の理解です。複雑ですね? –

2

onPause() - onResume() loopはonStart()を通過しません。これをアクティビティの開始時に実行する必要がある場合は、onResume()に配置します。あなたは常にonResume()を通過します。

+0

これは私の質問とは関係ありません。 – harmanjd

関連する問題