Android ProgressDialog не будет вращаться

Это мой первый пост, поэтому, пожалуйста, будьте осторожны со мной! Я уверен, что то, что я пытаюсь сделать, возможно, и это то, что я сделал (или не сделал?), Что вызывает проблему... Я просто не уверен, что это такое.

Что я пытаюсь сделать:
Показать ProgressDialog, пока мое приложение синхронизирует и обрабатывает загруженные данные.

Эта проблема:
ProgressDialog показывает, но не вращается (что делает его похожим на зависание), происходит синхронизация и обработка, ProgressDialog закрывается, приложение продолжает работать как обычно.

Как я в настоящее время пытаюсь сделать это:
Создать ProgressDialog - в моей деятельности
Сделай синхронизацию - в моем Сервисе
Обработка данных - в моем Сервисе
Удалите ПрогрессДиалог - в моей деятельности

Вещи, которые я пробовал:
Использование потока (код ниже) Использование AsynTask (может предоставить код при необходимости) Использование обработчика (может предоставить код при необходимости)

Потратив много времени на поиск ответа на мой вопрос, кажется, что у других была такая же или похожая проблема, и ей удалось решить ее с помощью одной из идей выше. Однако я не смог реализовать ни одну из этих идей, чтобы решить мою конкретную проблему. Это дает мне уверенность, что я что-то не так делаю... Я просто не знаю, что.

Исходный код, который я написал и использую в качестве основы для всех моих попыток исправления:
Первый

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 происходит в другом потоке, оставляя поток пользовательского интерфейса, не делая ничего, кроме как показать 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;
}

3 ответа

Решение

Проблема со счетчиком связана с ServiceConnection, который вы создаете в новом потоке. к сожалению для вас, это будет выполняться в вашей основной ветке / ветке графического интерфейса.

Из справочника по API: (http://developer.android.com/reference/android/content/ServiceConnection.html)

Как и многие обратные вызовы из системы, методы этого класса вызываются из основного потока вашего процесса.

Итак, поскольку я не знаком со службами, я могу только догадываться, что один из способов общения, когда ваша служба завершит загрузку данных, - это передать намерение, которое вы прослушиваете в своей деятельности, а затем остановить ProgressDialog. Но, конечно, есть и другие способы.

И как примечание, вы никогда не должны изменять графический интерфейс из какого-либо потока, кроме основного потока, что вы пытаетесь сделать, создав новый поток, который пытается закрыть диалоговое окно. Вы должны только закрыть диалог из основного потока.

Hay Можете ли вы попробовать использовать Handler?

Я думаю, что вы должны сделать это с помощью функции обработчика Android

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);
    }
}
Другие вопросы по тегам