2012-02-14 10 views
0

EDIT:SOLVED。申し訳ありませんが、私のデータの読み込みがバックグラウンドスレッドで行われている間に、データを解析したコールバックは発生していませんでした。データの解析には非常に時間がかかり、それがスレッドをロックしていたものです。UIスレッドをロックしてdoinbackgroundでASynchTaskをスリープします

EDIT:UIスレッドがブロックされているのではなく、ProgressDialogを使用しているという問題が、私の最も重要な問題(ProgressDialogが回転しなくなった)に起因する可能性があることがわかりました。そのような場合は、どうすれば修正できますか?

EDIT:明確にするために、これはプログラム全体を永久にロックしません。すべてがロードされると、進行状況ダイアログが閉じられ、新しいアクティビティが起動されます。私の問題は、それは、全体のUIはロックアップロードしている間ということである(すなわちprogressdialogが停止したスピニング)

TL; DRは:doInBackgroundでのThread.sleep()は()UIスレッド、私が持っている

をロックしています特定のアクティビティが開かれると、スケジュールに関連する大量のデータなど、バックエンドから多数のデータをバックグラウンドで読み込み始めます。この情報はすぐには使用されませんが、ユーザーがアクセスしようとすると(スケジュールボタンをクリックしてスケジュールアクティビティを起動して)使用することができます。

ユーザーは、スケジュールボタンをクリックする前に、データロードのすべてを少し待つ場合は、スケジュール・アクティビティが開き、偉大なすべてのものを表示します。私の問題は、データが読み込まれる前にボタンをクリックした場合です。ここ

私のソリューションは、定期的にデータの読み込みが完了したかどうかをチェックし、そうでない場合は寝ている間ProgressDialogを示しASyncTaskを作成することでした。データがいくつかのアプリケーション全体のブール変数を介してロードされたことを知っています。私の問題は、Thread.sleep()がdoinbackground()内で実行されても、UIスレッドをロックしているということです。

私は以下に定義されたカスタムASyncTask、使用しています

public class LoadWithProgressDialog extends AsyncTask<Void, Void, Boolean>{ 
    private ProgressDialog pd; //the progress dialog 
    private String title; //the title of the progress dialog 
    private String message; //the body of the progress dialog 
    private Runnable task; //contains the code we want to run in the background 
    private Runnable postTask; //execute when the task ends 
    private Context c; 


    public LoadWithProgressDialog(Context context,String t, String m,Runnable r, Runnable postR){ 
     super(); 
     c = context; 
     task = r; 
     postTask = postR; 
     title = t; 
     message = m; 
    } 

    @Override 
    protected void onPreExecute(){ 
     pd = ProgressDialog.show(c,title, message, false, false); 
    } 

    @Override 
    protected Boolean doInBackground(Void... params) { 
     task.run(); 
     return true; 
    } 


    @Override 
    protected void onPostExecute(Boolean result) { 
     pd.dismiss(); 
     if(postTask != null) 
      postTask.run(); 
    } 

と(例えば)を介して、それを呼び出す:

if(loadingSchedule){ 

      LoadWithProgressDialog lwpd = new LoadWithProgressDialog(thisClass,"Loading","Loading Schedule", new Runnable() { 
       public void run(){ 
        while(loadingSchedule){ 
          try { 
           Thread.sleep(1000); 
          } catch (InterruptedException e) { 
           e.printStackTrace(); 
          } 

        } 
       } 
      },new Runnable() { 
       public void run(){ 

        Intent i= new Intent(thisClass, Schedule.class); 
        i.putExtra("numberIneed",index); 
        startActivity(i); 
       } 
      }); 
      lwpd.execute(); 

(Iが "loadingSchedule" にグローバル変数へのアクセスを短縮します

UIスレッドをロックしないようにするにはどうすればよいですか?

答えて

0

コードが正しく表示され、メインスレッドをブロックしないでください。

デバッガを使用してください。 lwpd.executeの後にdoInBackground、Thread.sleep、onPostExecuteにブレークポイントを設定すると、コードがどこで取得され、どこで取得されるかがわかります。

「正確にUIスレッドがブロックされている場所」への回答を見つけようとします。

+0

申し訳ありませんが、私の編集を参照してください。バックグラウンド読み込みが完了すると、すべてが再び動作します。その期間だけロックされます(ProgressDialogは回転しません)。 UIがロックされたときを特定する方法はわかりません。なぜなら、progressdialogの回転を維持しなければならないコード以外のコードは実行されていないからです(私は書きませんでした)。 –

5

doInBackgroundでのThread.sleep()は()その名前が述べたように、UIスレッドをロックしない)UIスレッドdoInBackgroundで

のThread.sleepを()(ロックされ、タスクはバックグラウンドで行います非同期に。

あなたはUIスレッドがロックされません。実際にAsyncTaskが(onPreExecute()メソッドで)開始される前にProgressDialogのポップアップが表示され、AsyncTaskの実行中に(doInBackground()メソッドで)基本のアクティビティとのユーザーのやりとりがブロックされます。最後にAsyncTaskの終了後に終了します。 (onPostExecuteで()メソッド)私は、特定の活動が開いたときに、私のバックエンド

からバックグラウンドで大量のデータのロードを開始し、アプリを持っている

は、これが一般的ですデータのロードが完了したかどうか定期的に確認しながらProgressDialogを表示するASyncTaskを作成する代わりに、バックグラウンドでデータをロードするAsyncTask実装を作成する方が効率的です。

API hereをチェックしてください。正しく使用する方法の良い例が含まれています。

+0

1)ProgressDialogポップアップし、基本となるアクティビティとのユーザーのやりとりをブロックします。私の問題はPDが回転していないことです。私は、これがブロックされているUIスレッドを意味するかもしれないし、そうでないかもしれないことに気づいた。 2)バックグラウンドでデータをロードしています。この進行状況ダイアログは、準備が整う前にデータにアクセスしようとしているため、ユーザーは読み込みが完了するまで待つ必要があります。 –

+0

スピンの問題については、[this](http://stackoverflow.com/questions/3119676/android-progress-dialog-spinner-not-spinning)が役立つかどうかを確認してください。 – yorkw

+0

@yorkw私はDialogがUIをブロックするというこの問題を抱えています。あなたが知っているように、最初はメインスレッドで実行する必要があります –

関連する問題