Frage

Dies ist mein Faust -Stackoverflow -Beitrag, also bitte sei sanft mit mir! Ich bin sicher, dass das, was ich versuche zu tun etwas ist.

Was ich versuche zu tun:
Zeigen Sie einen ProgressDialog an, während meine App die heruntergeladenen Daten synchronisiert und verarbeitet.

Das Problem:
Der ProgressDialog zeigt aber nicht (was es so aussieht, als ob er eingefroren ist), die Synchronisation und Verarbeitung, die ProgressDialog schließt, die App dauert wie gewohnt.

Wie ich gerade dazu bin, das zu tun:
Erstellen Sie einen ProgressDialog - in meiner Aktivität
Machen Sie die Synchronisation - in meinem Dienst
Verarbeiten Sie die Daten - in meinem Dienst
Entbunden Sie den ProgressDialog - in meiner Aktivität

Die Dinge, die ich versucht habe:
Verwenden eines Threads (Code unten) mit einem Asyntask (kann bei Bedarf Code bereitstellen) mit einem Handler (kann bei Bedarf Code bereitstellen)

Nachdem sie viel Zeit damit verbracht haben, nach der Antwort auf meine Frage zu suchen, scheinen andere das gleiche oder ähnliches Problem zu haben und es geschafft, sie mit einer der obigen Ideen zu lösen. Ich konnte jedoch keine dieser Ideen implementieren, um mein spezielles Problem zu lösen. Das macht mich sicher, dass es etwas ist, das ich falsch mache ... Ich bin mir einfach nicht sicher, was.

Der ursprüngliche Code, den ich geschrieben habe und der ich als Grundlage für alle meine versuchten Korrekturen verwende:
Zuerst

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*/
    ...
}

dann

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;
    }
}

Jetzt gehe ich also davon aus, dass Dobind in einem anderen Thread stattfindet und den UI -Thread nichts anderes zu tun hat, als den Fortschrittsdialog zu zeigen ...?

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;
    }
}

Bitte lassen Sie mich wissen, ob Sie weitere Informationen benötigen, um mich bei diesem Problem zu unterstützen.


BEARBEITEN:

Hier ist der Code, den ich verwende, um stattdessen einen Handler zu verwenden. Dies zeigt das gleiche Verhalten (Spinner dreht sich nicht) wie zuvor.

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;
}
War es hilfreich?

Lösung

Das Problem mit dem Spinner hängt mit der ServicEConnection zusammen, die Sie im neuen Thread erstellen. Leider wird dies auf Ihrem Haupt -Thread / GUI -Thread ausgeführt.

Aus der API -Referenz: (http://developer.android.com/reference/android/content/serviceconnection.html)

Wie viele Rückrufe aus dem System werden die Methoden in dieser Klasse aus dem Hauptfaden Ihres Prozesses aufgerufen.

Da ich also nicht mit Diensten vertraut bin, kann ich nur vermuten, dass eine Art der Kommunikation, wenn Ihr Dienst fertig ist, um Daten herunterzuladen, eine Absicht übertragen, die Sie in Ihrer Aktivität anhören, und dann den ProgressDialog zu stoppen. Aber es gibt sicherlich auch andere Möglichkeiten.

Und als Randnotiz sollten Sie die GUI niemals von einem anderen Thread von einem anderen Thread ändern, den Sie durchführen möchten, indem Sie einen neuen Thread lasieren, der versucht, den Dialog zu entlassen. Sie sollten den Dialog nur aus dem Haupt -Thread abweisen.

Andere Tipps

Heu kannst du versuchen, Handler zu benutzen?

Ich denke, Sie sollten dies tun, indem Sie die Handlerfunktion von Android verwenden

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);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top