wake-up-neo.net

Aktivitätsklassenmethode aus Serviceklasse aufrufen

Ich habe in SO diesbezüglich viele Beiträge gesehen, konnte aber nicht die genaue und einfachste Methode zum Aufrufen einer Aktivitätsmethode aus der Serviceklasse erhalten. Ist der Broadcast-Empfänger nur die Option? Kein einfacher Ausweg ? Ich muss nur die folgende Methode in der Activity-Klasse aufrufen, nachdem der Media Player in der Service-Klasse vorbereitet wurde.

Aktivitätsklasse:

    public void updateProgress() {
    // set Progress bar values
    songProgressBar.setProgress(0);
    songProgressBar.setMax(100);
    // Updating progress bar
    updateProgressBar();
}

Serviceklasse:

   @Override
public IBinder onBind(Intent intent) {
    Log.d(this.getClass().getName(), "BIND");
    return musicBind;
}

@Override
public boolean onUnbind(Intent intent) {
    return false;
}
    @Override
public void onPrepared(MediaPlayer mp) {
    try {
        mp.start();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    }

           // updateProgress();// Need to call the Activity method here 
  }
41
Siju

Definieren Sie eine Schnittstelle, die Ihr Service zur Kommunikation von Ereignissen verwendet:

public interface ServiceCallbacks {
    void doSomething();
} 

Schreiben Sie Ihre Service-Klasse. Ihre Aktivität wird an diesen Dienst gebunden. Folgen Sie dem hier gezeigten Beispiel . Zusätzlich fügen wir eine Methode hinzu, um ServiceCallbacks festzulegen.

public class MyService extends Service {
    // Binder given to clients
    private final IBinder binder = new LocalBinder();
    // Registered callbacks
    private ServiceCallbacks serviceCallbacks;


    // Class used for the client Binder.
    public class LocalBinder extends Binder {
        MyService getService() {
            // Return this instance of MyService so clients can call public methods
            return MyService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    public void setCallbacks(ServiceCallbacks callbacks) {
        serviceCallbacks = callbacks;
    }
}

Schreiben Sie Ihre Activity-Klasse nach demselben Leitfaden, implementieren Sie jedoch auch Ihre ServiceCallbacks-Schnittstelle. Wenn Sie den Dienst binden/die Bindung aufheben, werden Sie ihn registrieren bzw. die Registrierung aufheben, indem Sie setCallbacks im Dienst aufrufen.

public class MyActivity extends Activity implements ServiceCallbacks {
    private MyService myService;
    private boolean bound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(...);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // bind to Service
        Intent intent = new Intent(this, MyService.class);
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from service
        if (bound) {
            myService.setCallbacks(null); // unregister
            unbindService(serviceConnection);
            bound = false;
        }
    }

    /** Callbacks for service binding, passed to bindService() */
    private ServiceConnection serviceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            // cast the IBinder and get MyService instance
            LocalBinder binder = (LocalBinder) service;
            myService = binder.getService();
            bound = true;
            myService.setCallbacks(MyActivity.this); // register
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            bound = false;
        }
    };

    /* Defined by ServiceCallbacks interface */
    @Override
    public void doSomething() {
        ...
    }
}

Wenn Ihr Dienst nun wieder mit der Aktivität kommunizieren möchte, rufen Sie einfach eine der Schnittstellenmethoden von früher auf. In Ihrem Dienst:

if (serviceCallbacks != null) { 
    serviceCallbacks.doSomething();
}
83
Karakuri

Verwenden Sie den Broadcast-Empfänger mit Dienst zum Aktualisieren Ihrer Ansicht aus der Dienstklasse . Beispiel:

  1. In meiner Aktivitätsklasse

    public class ServiceDemoActivity extends Activity {
    
        Intent intent;
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            final TextView notification = (TextView) findViewById(R.id.notification);
            if (CheckIfServiceIsRunning()) {
    
            } else {
                startService(new Intent(this, MyService.class));
            }
        }
    
        private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updateDate(intent);
            }
        };
    
        private void updateDate(Intent intent) {
            String time = intent.getStringExtra("time");
            Toast.makeText(getApplicationContext(), "Yea!!! Service called", Toast.LENGTH_SHORT).show();
            TextView date = (TextView) findViewById(R.id.date);
            date.setText(time);
        }
    
        @Override
        public void onResume() {
            super.onResume();
            registerReceiver(broadcastReceiver, new IntentFilter(
                    MyService.BROADCAST_ACTION));
        }
    }
    

    In meiner Service-Klasse rufe ich nach einiger Zeit, in der meine Benutzeroberfläche aktualisiert wird, mein Update auf.

    public class MyService extends Service {    
    
            public static final String
            BROADCAST_ACTION = "com.mukesh.service";    
            private final Handler handler = new Handler();
    
    
            @Override
            public void onCreate() {
    
                intent = new Intent(BROADCAST_ACTION);
            }
    
            @Override   
            public void onDestroy() {
    
                stopService(intent);
            }
    
            @Override
            public void onStart(Intent intent, int startid) {
                int i = 0;
                while (i <= 2) {
                    if (i > 1) {
                        i++;
                        this.onDestroy();
                    } else {
                        counter = i;
                        i++;
                        handler.removeCallbacks(sendUpdatesToUI);
                        handler.postDelayed(sendUpdatesToUI, 1 * 1000); // 1 sec
                    }
                }       
            }
    
            private Runnable sendUpdatesToUI = new Runnable() {
                public void run() {
                    DisplayLoggingInfo();           
                            handler.postDelayed(this, 7 * 1000); // 7 sec
                }
            };
    
            private void DisplayLoggingInfo() {  
                intent.putExtra("time", new Date().toLocaleString());
                intent.putExtra("counter", String.valueOf(counter));
                sendBroadcast(intent);
                stopService(intent);
            }
     }
    

Vollständigen Code finden Sie unter link

5
Mukesh Y

Ich habe eine allgemeine Klasse namens Delegate erstellt (dies ist kein spezieller Name, Sie können sie John nennen) und die MainActivity-Klasse als statisches Feld übergeben. Dann kann ich vom Dienst aus auf den Dienst zugreifen. Ich bin nicht sicher, ob es kostengünstig ist, aber es hat das Problem für mich einfach gelöst.

Mein Service: 

package com.some.package;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

public class FirebaseInstanceIDService extends FirebaseInstanceIdService {

    @Override
    public void onTokenRefresh() {
        String token = FirebaseInstanceId.getInstance().getToken();
        Delegate.theMainActivity.onDeviceTokenChange(token);
    }
}

Delegierte Klasse:

package com.some.package;

public class Delegate {
    static MainActivity theMainActivity;
}

Was ich in MainActivity gemacht habe:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Delegate.theMainActivity = this;

    //rest of the code...
}

public void onDeviceTokenChange(String token){
    Log.e("updated token:", token);
}
2
fenadoruk

Sie können Ihre Dienstmethode nicht direkt aus Ihrer Aktivität oder umgekehrt aufrufen. Es gibt drei Möglichkeiten, mit einem Dienst zu kommunizieren. Verwenden von Broadcastern und Empfängern, Verwenden von Messenger oder Binden an den Dienst. Weitere Informationen finden Sie unter http://developer.Android.com/guide/components/bound-services.html

0
Onur

Sie können von Ihrem Dienst anrufen

 getContentResolver().notifyChange(uri, null);

und in Ihrer Aktivität richten Sie ein

getContentResolver().registerContentObserver(uri, false, new ContentObserver(getHandler())
{
    public void onChange(boolean selfChange)
    {
        updateProgress()
    }
};

die onChange-Methode wird für den UI-Thread aufgerufen

0
asaf gitai

Sie können eine Aktivitätsmethode aus dem Dienst aufrufen, indem Sie Ihren eigenen Listener wie folgt implementieren https://stackoverflow.com/a/18585247/5361964

Sie könnten Ihre Aktivitätsmethode in runOnUiThread wie folgt ausführen:

    // method will be called from service
    override fun callback(activity: Activity, result: String) {
        runOnUiThread{
            Toast.makeText(activity, result, Toast.LENGTH_LONG).show()
        }
    }
0
Zohab Ali