5

これは私の最初のstackoverflowポストですので、私に優しくしてください!私がやろうとしていることは可能であると確信しており、問題を引き起こしているのは私が行った(または行っていない?)ことです...私はそれが何であるがわかりません。

私がやろうとしていること:
アプリがダウンロードされたデータを同期して処理している間、ProgressDialogを表示します。

問題:
ProgressDialogは表示されますが、回転しません(これにより、フリーズしたように見えます)。同期と処理が行われ、ProgressDialogが閉じ、アプリは通常どおり続行します。

現在どのようにそれを実行しようとしていますか:
ProgressDialogを作成します-アクティビティ
で同期を実行します-サービス
でデータを処理します-サービス
でProgressDialogを破棄します-アクティビティで

私が試したこと:
スレッドの使用(以下のコード)AsynTaskの使用(必要に応じてコードを提供できます)ハンドラーの使用(必要に応じてコードを提供できます)

私の質問に対する答えを探すのに多くの時間を費やした後、他の人が同じまたは同様の問題を抱えていて、上記のアイデアの1つを使用してそれを解決することができたようです。しかし、私は特定の問題を解決するためにこれらのアイデアを実装することができませんでした。これは私が間違っていることであると私に確信させます...私はただ何がわからないのです。

私が作成し、試行したすべての修正の基礎として使用している元のコード:
最初に

public class myActivity extends ListActivity {
    private ProgressDialog dialog;
    private boolean mIsBound;
    private myService mBoundService;
    private ServiceConnection mConnection;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /*if we need to login start login activity for result*/
        ...
    }

    ...
    /*other methods*/
    ...
}

それから

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    switch (requestCode){
        case ACTIVITY_LOGIN:
            /*after login we know we always need to sync*/
         dialog = new ProgressDialog(myActivity.this);
         dialog.setMessage("Synchronising...");
         dialog.setIndeterminate(true);
         dialog.setCancelable(false);
         dialog.show();

            Thread doBind = new Thread(new Runnable(){public void run(){doBindService();}});
            doBind.start();
            break;
    }
}

だから今私はdoBindが別のスレッドで起こっていると仮定してUIスレッドをProgressDialogueを表示する以外に何もすることはありません...?

private boolean doBindService() {
 mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mBoundService = ((myService.LocalBinder)service).getService();      
            while (mBoundService.isRunning()){
                /*wait for service to finish before doing anything else... myMethod() is expecting the sync to have completed*/
                /*I suspect this loop to be the thing causing the problem. But I'm not sure why because it is in a different thread so shouldn't interfear with the dialog?! And if that is what is causing the problem then how else can I do this?*/
            }
            /*get the activity to do Stuff with the downloaded data*/
            myMethod();
            /*finished with the service for now so unbind*/
            doUnbindService();
            if (dialog != null) {
                dialog.dismiss();
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            mBoundService = null;
        }
    };

    boolean myReturn = bindService(new Intent(myActivity.this, myService.class), mConnection, Context.BIND_AUTO_CREATE);
    mIsBound = myReturn;
 return myReturn;
}

private void doUnbindService() {
    if (mIsBound) {
        unbindService(mConnection);
        mIsBound = false;
    }
}

この問題についてサポートが必要な場合は、お知らせください。


編集:

代わりにハンドラーを使用するために使用しているコードは次のとおりです。これは、以前と同じ動作(スピナーは回転しません)を表示します。

Thread doBind = new Thread(new Runnable(){
    public void run(){
        doBindService();
    }
});
doBind.start();

private Handler handler = new Handler() {
    @Override
public void handleMessage(Message msg) {
    dialog.dismiss();
}
};

private boolean doBindService() {
 mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mBoundService = ((myService.LocalBinder)service).getService();      
            while (mBoundService.isRunning()){
            }
            //...do stuff same as before...
            handler.sendEmptyMessage(0);
        }

        public void onServiceDisconnected(ComponentName className) {
            mBoundService = null;
        }
    };

    boolean myReturn = bindService(new Intent(myActivity.this, myService.class), mConnection, Context.BIND_AUTO_CREATE);
    mIsBound = myReturn;
 return myReturn;
}
4

3 に答える 3

2

スピナーの問題は、新しいスレッドで作成するServiceConnectionに関連しています。残念ながら、これはメインスレッド/GUIスレッドで実行されます。

APIリファレンスから:(http://developer.android.com/reference/android/content/ServiceConnection.html)

システムからの多くのコールバックと同様に、このクラスのメソッドはプロセスのメインスレッドから呼び出されます。

したがって、私はサービスに精通していないため、サービスのダウンロードが完了したときに通信する1つの方法は、アクティビティでリッスンするインテントをブロードキャストしてから、ProgressDialogを停止することだと推測できます。しかし、確かに他の方法もあります。

また、補足として、ダイアログを閉じようとする新しいスレッドを生成することによって実行しようとしているメインスレッド以外のスレッドからGUIを変更しないでください。メインスレッドからダイアログを閉じるだけです。

于 2010-11-17T15:31:43.507 に答える
0

干し草ハンドラーを使ってみませんか?

Androidのハンドラー機能を使ってやるべきだと思います

于 2010-11-17T13:21:16.083 に答える
0
public class yourclass extends Activity implements Runnable {

    static ProgressDialog progressDialog;

    @Override
    public void onCreate(Bundle icicle) {
                progressDialog = ProgressDialog.show(keywordview.this, "", "Loading...", true);
                Thread thread = new Thread(keywordview.this);

    }
    final Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            progressDialog.dismiss();
        /*Here you can handle you process*/
        }
    };

    public void run() {
        //here your code for run 
        handler.sendEmptyMessage(0);
    }
}
于 2010-11-18T04:47:28.463 に答える