[解決済み] Android SDK AsyncTask doInBackground が実行されない (サブクラス)
質問
2012年2月15日現在、私はまだこれが機能しない理由に対する良い説明や理由を見つけることができません。解決策に最も近いのは、従来の スレッド アプローチですが、それではなぜAndroid SDKで動作しない(ように見える)クラスをインクルードするのでしょうか?
こんばんは、SO!
AsyncTaskのサブクラスを持っています。
// ParseListener had a callback which was called when an item was parsed in a
// RSS-xml, but as stated further down it is not used at all right now.
private class xmlAsync extends AsyncTask<String, RSSItem, Void> implements ParseListener
それがこのように実行されます。
xmlAsync xmlThread = new xmlAsync();
xmlThread.execute("http://www.nothing.com");
さて、このサブクラスはちょっとしたエラーに見舞われました。以前は xml パースを行っていましたが、気づいたときには doInBackground() が呼び出されていないことに気づいたとき、私はそれを一行ずつ削除し、最終的にこれだけになりました。
@Override
protected Void doInBackground(String... params)
{
Log.v(TAG, "doInBackground");
return null;
}
これは、なぜか何もログに残りません。しかし、私はこれを追加しました。
@Override
protected void onPreExecute()
{
Log.v(TAG, "onPreExecute");
super.onPreExecute();
}
そしてその行は、スレッドを実行する際に確かにログに記録されます。 つまり、どういうわけか onPreExecute() は呼び出されますが、doInBackground() は呼び出されないのです。 . 私は同時にバックグラウンドで実行されている別のAsyncTaskを持っており、それはうまく動作しています。
私は現在、SDK Version 15、Eclipse、Mac OS X 10.7.2 のエミュレーター上で、北極に近い場所でアプリを実行しています。
EDITです。
@Override
protected void onProgressUpdate(RSSItem... values) {
if(values[0] == null)
{
// activity function which merely creates a dialog
showInputError();
}
else
{
Log.v(TAG, "adding "+values[0].toString());
_tableManager.addRSSItem(values[0]);
}
super.onProgressUpdate(values);
}
_tableManager.addRSSItem() は多かれ少なかれ、アクティビティのコンテキストで初期化された SQLiteDatabase に行を追加します。publishProgress() は Interface ParseListener のコールバックによって呼び出されます。しかし、私はdoInBackground()でlog.vを除いて何もしないので、私は最初にこれを持ち出すことさえ不要であることがわかりました。
EDIT 2:
さて、完全に明確にするために、これは他のAsyncTaskであり、同じアクティビティで実行され、完全にうまく動作しています。
private class dbAsync extends AsyncTask<Void, RSSItem, Void>
{
Integer prevCount;
boolean run;
@Override
protected void onPreExecute() {
run = true;
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
run = true;
prevCount = 0;
while(run)
{
ArrayList<RSSItem> items = _tableManager.getAllItems();
if(items != null)
{
if(items.size() > prevCount)
{
Log.v("db Thread", "Found new item(s)!");
prevCount = items.size();
RSSItem[] itemsArray = new RSSItem[items.size()];
publishProgress(items.toArray(itemsArray));
}
}
SystemClock.sleep(5000);
}
return null;
}
@Override
protected void onProgressUpdate(RSSItem... values) {
ArrayList<RSSItem> list = new ArrayList<RSSItem>();
for(int i = 0; i < values.length; i++)
{
list.add(i, values[i]);
}
setItemsAndUpdateList(list);
super.onProgressUpdate(values);
}
@Override
protected void onCancelled() {
run = false;
super.onCancelled();
}
}
EDIT 3:
はぁ~、質問下手ですいません。でも、タスクの初期化はこんな感じです。
xmlAsync _xmlParseThread;
dbAsync _dbLookup;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_dbLookup = new dbAsync();
_dbLookup.execute();
_xmlParseThread = new xmlAsync();
_xmlParseThread.execute("http://www.nothing.com", null);
}
どのように解決するのですか?
Matthieu の解決策は、ほとんどの場合うまくいきますが、一部の人は問題に直面する可能性があります。 Anders Göransson の説明のように。 私はここで他の記事を要約し、executeOnExecutorがまだシングルスレッドで動作している場合の解決策をすばやく説明しようとしています...
の挙動
AsyncTask().execute();
の挙動は、Androidのバージョンによって変化しています。以前は
ドーナツ
(アンドロイド:1.6 API:4)
のタスクが順次実行されました。
ドーナツ
から
ジンジャーブレッド
(Android:2.3 API:9)
タスクが並列に実行されるようになりました。
ハニカム
(アンドロイド:3.0 API:11)
の実行がシーケンシャルに戻され、新しいメソッド
AsyncTask().executeOnExecutor(Executor)
が追加され、並列実行が可能になりました。
逐次処理では、すべての Async タスクは単一のスレッドで実行されるため、前のタスクが終了する前に待機する必要があります。すぐにコードを実行する必要がある場合、タスクは別々のスレッドで並列に処理される必要があります。
AsyncTask のシリアル実行は Donut と Honeycomb バージョンの間では利用できず、一方、並列実行は Donut よりも前に利用できません。
Donut以降の並列処理について。Buildのバージョンを確認し、それに基づいて.execute()または.executeOnExecutor()メソッドを使用します。以下のコードが参考になります。
AsyncTask<Void,Void,Void> myTask = new AsyncTask<Void,Void,Void>() { ... }; // ... your AsyncTask code goes here
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
myTask.execute();
NOTE:
機能
.executeOnExecutor()
は
targetSdkVersion
と同じかそれ以下であるかどうかを調べます。
HONEYCOMB_MR1
(Android:2.1 API:7)であれば、強制的にエグゼキュータが
THREAD_POOL_EXECUTOR
(ポストHoneycombでTasksを順次実行する)となります。
を定義していない場合は
targetSdkVersion
であれば
minSdkVersion
は自動的に
targetSdkVersion
.
したがって、ポストハニカムのAsyncTaskを並列に実行するために
targetSdkVersion
を空にすることはできません。
関連
-
[解決済み】Android 8:クリアテキストのHTTPトラフィックが許可されない
-
[解決済み] Androidでサービスが稼働しているかどうかを確認する方法を教えてください。
-
[解決済み] AsyncTaskのAndroidサンプル
-
[解決済み] BottomSheetDialogFragmentの状態をexpandedに設定する。
-
[解決済み] CardView layout_width="match_parent "が親のRecyclerViewの幅と一致しない。
-
[解決済み] Androidでマイナスマージンを使用するのは悪いことですか?
-
[解決済み] DialogFragmentを正しく終了させるには?
-
[解決済み] フラグメント間の値の受け渡し方法
-
[解決済み] アンドロイドのdatepickerダイアログで最大の日付を設定するには?
-
[解決済み] Androidでツールバーの戻るボタンの色を変えるには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】複数のAsyncTasksを同時に実行することは不可能か?
-
[解決済み] 設定ページに移動せずに位置情報サービスをオンにする
-
[解決済み] Nexus 4でUSBデバッグモードを見つける方法とオンにする方法
-
[解決済み] プログラム的に電話をかけるには?
-
[解決済み] XMLで矩形を描画できますか?
-
[解決済み] APKが署名済みかデバッグビルドかを確認するには?
-
[解決済み] AndroidでTextViewの下にアンダーラインを引くには
-
[解決済み] react nativeアプリのバージョン番号を更新する方法
-
[解決済み] AsyncTaskLoaderとAsyncTaskの比較
-
[解決済み] google-services.jsonって実際何してるの?