9

ProgressDialog を機能させるには、AsyncTask を Activity クラス内の内部クラスにする必要があると考え始めています。真実?[かなり後で編集されました...答えは False で、これがバグなのか何なのかわかりません。Android1.5を使用しています。サービスについて調べてみます。]

データベースを使用して情報を操作する活動があります。データベースにデータが入力されていれば、すべて問題ありません。データが入力されていない場合は、Web サイトから情報をダウンロードし、データベースにデータを入力してから、入力されたデータベースにアクセスして onCreate のビューを完成させる必要があります。

問題は、AsyncTask スレッドがデータベースへのデータの取り込みをいつ終了したかを判断する手段がないことです。次の強制終了エラー メッセージが表示されます。申し訳ありません。アプリケーションが予期せず停止しました。[Force Close] ボタンをクリックすると、バックグラウンドの AsyncTask スレッドが引き続き機能し、データベースにデータが入力され、すべてが正常に機能します。

そのエラーメッセージを取り除く必要があり、これを行う方法について助けが必要です. ここにいくつかの疑似コードがあります:

public class ViewStuff extends Activity
{
  onCreate
  { 
    if(database is populated)
      do_stuff
    else
    {
      FillDB task = null;
      if(task == null || task.getStatus().equals(AsyncTask.Status.FINISHED))
       {                
         task = new FillDB(context);
         task.execute(null);
       }
    }

  continue with onCreate using information from database to properly display 

 } // end onCreate
} // end class

別のファイルで:

public class FillDB extends AsyncTask<Void, Void, Void>
{
    private Context context;

    public FillDB (Context c)  //pass the context in the constructor
{
    context = c;
}

    public void filldb ()
    {
      doInBackground();
    }

    @Override
    protected void onPreExecute()
    {          
       ProgressDialog progressDialog = new ProgressDialog(context);
       //crashes with the following line
       progressDialog.show(context, "Working..", "Retrieving info");
    }

    @Override
    protected Void doInBackground(Void... params)
    {
  // TODO Auto-generated method stub

try
     etc etc etc
    }
 }

エミュレータからのスタック トレースは次のとおりです。

----- pid 846 at 2010-03-21 19:58:25 -----
Cmd line: com.trial

DALVIK THREADS:
"main" prio=5 tid=3 NATIVE
 | group="main" sCount=1 dsCount=0 s=0 obj=0x40018e70
 | sysTid=846 nice=0 sched=0/0 handle=-1098855268
 at android.os.BinderProxy.transact(Native Method)
 at      android.app.ActivityManagerProxy.handleApplicationError(ActivityManagerNative.java:2103)
 at com.android.internal.os.RuntimeInit.crash(RuntimeInit.java:302)
 at   com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:75)
 at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:887)
 at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:884)
 at dalvik.system.NativeStart.main(Native Method)

 "Binder Thread #3" prio=5 tid=15 NATIVE
 | group="main" sCount=1 dsCount=0 s=0 obj=0x43733d88
 | sysTid=852 nice=0 sched=0/0 handle=1486928
 at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #2" prio=5 tid=13 NATIVE
 | group="main" sCount=1 dsCount=0 s=0 obj=0x437313c8
 | sysTid=851 nice=0 sched=0/0 handle=1492472
 at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #1" prio=5 tid=11 NATIVE
 | group="main" sCount=1 dsCount=0 s=0 obj=0x4372b9b0
 | sysTid=850 nice=0 sched=0/0 handle=1492664
 at dalvik.system.NativeStart.run(Native Method)

"JDWP" daemon prio=5 tid=9 VMWAIT
 | group="system" sCount=1 dsCount=0 s=0 obj=0x4372a2a0
 | sysTid=849 nice=0 sched=0/0 handle=1490176
 at dalvik.system.NativeStart.run(Native Method)

"Signal Catcher" daemon prio=5 tid=7 RUNNABLE
| group="system" sCount=0 dsCount=0 s=0 obj=0x4372a1e8
| sysTid=848 nice=0 sched=0/0 handle=1487888
 at dalvik.system.NativeStart.run(Native Method)

"HeapWorker" daemon prio=5 tid=5 VMWAIT
 | group="system" sCount=1 dsCount=0 s=0 obj=0x427d03c0
 | sysTid=847 nice=0 sched=0/0 handle=1487592
 at dalvik.system.NativeStart.run(Native Method)

 ----- end 846 -----

私は何を間違っていますか?

スノーフレークさん、

試した:

@Override
protected void onPreExecute()
{

Activity.this.runOnUiThread(new Runnable() {
      public void run() {
        ProgressDialog progressDialog = new ProgressDialog(context);
        //crashes with the following line
        progressDialog.show(context, "Working..", "Retrieving info");
      }
    });
}

Activity.this はエラーとしてフラグが立てられています: タイプ Activity の囲んでいるインスタンスはスコープ内でアクセスできません

FillDB が Activity を拡張し、AsyncTask を拡張する FillDB 内にプライベート クラスを作成する必要があると考えていますか? それはうまくいきません。FillDB アクティビティがいつ開始されるかは保証されず、完了時に AsyncTask から結果が返されないため、startActivityForResult を使用できません。

更新:呼び出し元のクラスにプライベート クラスを作成しようとしました。まだ ProgressDialog を表示できません。エラーの 1 つ: ウィンドウを追加できません -- トークン null はアプリケーション用ではありません。どのトークンが参照されているのかわかりません。

4

4 に答える 4

2

AsyncTask をあきらめ、Handler を使用して Thread を処理しました。すべてが良いです。

AsyncTask を使用した 1.5 のバグなのか、それとも私がしなかった何かのバグなのかはわかりません。

于 2010-03-28T23:37:00.207 に答える
2

ダイアログを実装するために onCreateDialog() メソッドをオーバーライドすることを検討しましたか? Android がほとんどの作業を行うため、この方法でそれらを簡単に作成および制御できます。以下に、あなたがやろうとしていることを正確に実行する例を示します。

http://pastie.org/880540

于 2010-03-22T05:28:28.637 に答える
0

私は、パブリック(外部)AsyncTaskでかなり長い間OPと同じ問題を抱えていました。「非アプリケーショントークンでウィンドウを追加しようとしました」というエラーメッセージを調べたところ、AsyncTaskのコンストラクターで渡されるコンテキストの設定に問題があることがわかりました。渡される必要があるコンテキストは「this」であり、this.getApplicationContext()またはthis.getBaseContext()ではありません。それで私の問題は解決しました。

于 2010-07-20T20:57:59.870 に答える
0

実行してみてください

   ProgressDialog progressDialog = new ProgressDialog(context);
   //crashes with the following line
   progressDialog.show(context, "Working..", "Retrieving info");

Activity.runOnUiThread() の引数としてランナブルとして。ユーザー インターフェイス要素は、UI スレッドで作成および操作する必要があります。これは s にも当てはまると思いますDialog

[編集] コード:

Activity.this.runOnUiThread(new Runnable() {
  public void run() {
    ProgressDialog progressDialog = new ProgressDialog(context);
    //crashes with the following line
    progressDialog.show(context, "Working..", "Retrieving info");
  }
};
于 2010-03-21T18:05:57.440 に答える