Android ProgressDialog не будет вращаться - PullRequest
5 голосов
/ 17 ноября 2010

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

Что я пытаюсь сделать:
Показать 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;
    }
}

Пожалуйста, дайте мне знать, если вам потребуется дополнительная информация, чтобы помочь мне с этой проблемой.


EDIT:

Вот код, который я использую для использования обработчика. Это показывает то же поведение (спиннер не вращается), как раньше.

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 ]

2 голосов
/ 17 ноября 2010

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

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

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

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

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

0 голосов
/ 18 ноября 2010
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);
    }
}
0 голосов
/ 17 ноября 2010

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

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

...