Contoh: Komunikasi antara Aktivitas dan Layanan menggunakan Pesan

584

Saya tidak dapat menemukan contoh cara mengirim pesan antara aktivitas dan layanan, dan saya telah menghabiskan waktu terlalu banyak untuk mencari tahu. Ini adalah contoh proyek untuk referensi orang lain.

Contoh ini memungkinkan Anda untuk memulai atau menghentikan layanan secara langsung, dan secara terpisah mengikat / melepaskan ikatan dari layanan. Ketika layanan berjalan, ia menambah angka pada 10 Hz. Jika aktivitas terikat ke Service, itu akan menampilkan nilai saat ini. Data ditransfer sebagai Integer dan sebagai String sehingga Anda dapat melihat bagaimana melakukan itu dengan dua cara berbeda. Ada juga tombol dalam aktivitas untuk mengirim pesan ke layanan (mengubah nilai tambah demi nilai).

Tangkapan layar:

Cuplikan layar contoh layanan pesan Android

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.exampleservice"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    <service android:name=".MyService"></service>
    </application>
    <uses-sdk android:minSdkVersion="8" />
</manifest>

res \ values ​​\ strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ExampleService</string>
    <string name="service_started">Example Service started</string>
    <string name="service_label">Example Service Label</string>
</resources>

res \ layout \ main.xml:

<RelativeLayout
    android:id="@+id/RelativeLayout01"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/btnStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Service" >
    </Button>

    <Button
        android:id="@+id/btnStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Stop Service" >
    </Button>
</RelativeLayout>

<RelativeLayout
    android:id="@+id/RelativeLayout02"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/btnBind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Bind to Service" >
    </Button>

    <Button
        android:id="@+id/btnUnbind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Unbind from Service" >
    </Button>
</RelativeLayout>

<TextView
    android:id="@+id/textStatus"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Status Goes Here"
    android:textSize="24sp" />

<TextView
    android:id="@+id/textIntValue"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Integer Value Goes Here"
    android:textSize="24sp" />

<TextView
    android:id="@+id/textStrValue"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="String Value Goes Here"
    android:textSize="24sp" />

<RelativeLayout
    android:id="@+id/RelativeLayout03"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/btnUpby1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Increment by 1" >
    </Button>

    <Button
        android:id="@+id/btnUpby10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="Increment by 10" >
    </Button>
</RelativeLayout>

src \ com.exampleservice \ MainActivity.java:

package com.exampleservice;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
    Button btnStart, btnStop, btnBind, btnUnbind, btnUpby1, btnUpby10;
    TextView textStatus, textIntValue, textStrValue;
    Messenger mService = null;
    boolean mIsBound;
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MyService.MSG_SET_INT_VALUE:
                textIntValue.setText("Int Message: " + msg.arg1);
                break;
            case MyService.MSG_SET_STRING_VALUE:
                String str1 = msg.getData().getString("str1");
                textStrValue.setText("Str Message: " + str1);
                break;
            default:
                super.handleMessage(msg);
            }
        }
    }
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mService = new Messenger(service);
            textStatus.setText("Attached.");
            try {
                Message msg = Message.obtain(null, MyService.MSG_REGISTER_CLIENT);
                msg.replyTo = mMessenger;
                mService.send(msg);
            }
            catch (RemoteException e) {
                // In this case the service has crashed before we could even do anything with it
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been unexpectedly disconnected - process crashed.
            mService = null;
            textStatus.setText("Disconnected.");
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStart = (Button)findViewById(R.id.btnStart);
        btnStop = (Button)findViewById(R.id.btnStop);
        btnBind = (Button)findViewById(R.id.btnBind);
        btnUnbind = (Button)findViewById(R.id.btnUnbind);
        textStatus = (TextView)findViewById(R.id.textStatus);
        textIntValue = (TextView)findViewById(R.id.textIntValue);
        textStrValue = (TextView)findViewById(R.id.textStrValue);
        btnUpby1 = (Button)findViewById(R.id.btnUpby1);
        btnUpby10 = (Button)findViewById(R.id.btnUpby10);

        btnStart.setOnClickListener(btnStartListener);
        btnStop.setOnClickListener(btnStopListener);
        btnBind.setOnClickListener(btnBindListener);
        btnUnbind.setOnClickListener(btnUnbindListener);
        btnUpby1.setOnClickListener(btnUpby1Listener);
        btnUpby10.setOnClickListener(btnUpby10Listener);

        restoreMe(savedInstanceState);

        CheckIfServiceIsRunning();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("textStatus", textStatus.getText().toString());
        outState.putString("textIntValue", textIntValue.getText().toString());
        outState.putString("textStrValue", textStrValue.getText().toString());
    }
    private void restoreMe(Bundle state) {
        if (state!=null) {
            textStatus.setText(state.getString("textStatus"));
            textIntValue.setText(state.getString("textIntValue"));
            textStrValue.setText(state.getString("textStrValue"));
        }
    }
    private void CheckIfServiceIsRunning() {
        //If the service is running when the activity starts, we want to automatically bind to it.
        if (MyService.isRunning()) {
            doBindService();
        }
    }

    private OnClickListener btnStartListener = new OnClickListener() {
        public void onClick(View v){
            startService(new Intent(MainActivity.this, MyService.class));
        }
    };
    private OnClickListener btnStopListener = new OnClickListener() {
        public void onClick(View v){
            doUnbindService();
            stopService(new Intent(MainActivity.this, MyService.class));
        }
    };
    private OnClickListener btnBindListener = new OnClickListener() {
        public void onClick(View v){
            doBindService();
        }
    };
    private OnClickListener btnUnbindListener = new OnClickListener() {
        public void onClick(View v){
            doUnbindService();
        }
    };
    private OnClickListener btnUpby1Listener = new OnClickListener() {
        public void onClick(View v){
            sendMessageToService(1);
        }
    };
    private OnClickListener btnUpby10Listener = new OnClickListener() {
        public void onClick(View v){
            sendMessageToService(10);
        }
    };
    private void sendMessageToService(int intvaluetosend) {
        if (mIsBound) {
            if (mService != null) {
                try {
                    Message msg = Message.obtain(null, MyService.MSG_SET_INT_VALUE, intvaluetosend, 0);
                    msg.replyTo = mMessenger;
                    mService.send(msg);
                }
                catch (RemoteException e) {
                }
            }
        }
    }


    void doBindService() {
        bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
        mIsBound = true;
        textStatus.setText("Binding.");
    }
    void doUnbindService() {
        if (mIsBound) {
            // If we have received the service, and hence registered with it, then now is the time to unregister.
            if (mService != null) {
                try {
                    Message msg = Message.obtain(null, MyService.MSG_UNREGISTER_CLIENT);
                    msg.replyTo = mMessenger;
                    mService.send(msg);
                }
                catch (RemoteException e) {
                    // There is nothing special we need to do if the service has crashed.
                }
            }
            // Detach our existing connection.
            unbindService(mConnection);
            mIsBound = false;
            textStatus.setText("Unbinding.");
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            doUnbindService();
        }
        catch (Throwable t) {
            Log.e("MainActivity", "Failed to unbind from the service", t);
        }
    }
}

src \ com.exampleservice \ MyService.java:

package com.exampleservice;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class MyService extends Service {
    private NotificationManager nm;
    private Timer timer = new Timer();
    private int counter = 0, incrementby = 1;
    private static boolean isRunning = false;

    ArrayList<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients.
    int mValue = 0; // Holds last value set by a client.
    static final int MSG_REGISTER_CLIENT = 1;
    static final int MSG_UNREGISTER_CLIENT = 2;
    static final int MSG_SET_INT_VALUE = 3;
    static final int MSG_SET_STRING_VALUE = 4;
    final Messenger mMessenger = new Messenger(new IncomingHandler()); // Target we publish for clients to send messages to IncomingHandler.


    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
    class IncomingHandler extends Handler { // Handler of incoming messages from clients.
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_REGISTER_CLIENT:
                mClients.add(msg.replyTo);
                break;
            case MSG_UNREGISTER_CLIENT:
                mClients.remove(msg.replyTo);
                break;
            case MSG_SET_INT_VALUE:
                incrementby = msg.arg1;
                break;
            default:
                super.handleMessage(msg);
            }
        }
    }
    private void sendMessageToUI(int intvaluetosend) {
        for (int i=mClients.size()-1; i>=0; i--) {
            try {
                // Send data as an Integer
                mClients.get(i).send(Message.obtain(null, MSG_SET_INT_VALUE, intvaluetosend, 0));

                //Send data as a String
                Bundle b = new Bundle();
                b.putString("str1", "ab" + intvaluetosend + "cd");
                Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
                msg.setData(b);
                mClients.get(i).send(msg);

            }
            catch (RemoteException e) {
                // The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
                mClients.remove(i);
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("MyService", "Service Started.");
        showNotification();
        timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 0, 100L);
        isRunning = true;
    }
    private void showNotification() {
        nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        // In this sample, we'll use the same text for the ticker and the expanded notification
        CharSequence text = getText(R.string.service_started);
        // Set the icon, scrolling text and timestamp
        Notification notification = new Notification(R.drawable.icon, text, System.currentTimeMillis());
        // The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);
        // Send the notification.
        // We use a layout id because it is a unique number.  We use it later to cancel.
        nm.notify(R.string.service_started, notification);
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("MyService", "Received start id " + startId + ": " + intent);
        return START_STICKY; // run until explicitly stopped.
    }

    public static boolean isRunning()
    {
        return isRunning;
    }


    private void onTimerTick() {
        Log.i("TimerTick", "Timer doing work." + counter);
        try {
            counter += incrementby;
            sendMessageToUI(counter);

        }
        catch (Throwable t) { //you should always ultimately catch all exceptions in timer tasks.
            Log.e("TimerTick", "Timer Tick Failed.", t);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (timer != null) {timer.cancel();}
        counter=0;
        nm.cancel(R.string.service_started); // Cancel the persistent notification.
        Log.i("MyService", "Service Stopped.");
        isRunning = false;
    }
}
Lance Lefebure
sumber
53
Contoh yang bagus! Fitur bagus lainnya: Jika Anda menempatkan android:process=:myservicenameatribut ke servicetag layanan Anda di manifest.xml Anda, seperti:, <service android:name="sname" android:process=":myservicename" />maka itu akan menjalankan layanan Anda sebagai proses yang berbeda - dengan demikian di utas yang berbeda. Ini berarti, bahwa setiap perhitungan berat dilakukan / permintaan panjang oleh layanan tidak akan menggantung utas UI Anda.
sydd
28
Saya tahu Anda telah melakukan upaya ini, tetapi akan lebih masuk akal untuk meletakkannya di github atau situs berbagi kode sumber serupa dan memposting tautan di sini. Lebih mudah bagi orang untuk bangkit dan menjalankannya dengan cara ini.
Ehtesh Choudhury
25
Contoh yang baik. Saya meletakkan kode ini di repo online (dengan modifikasi kecil) bagi mereka yang ingin mengkloning: bitbucket.org/alexfu/androidserviceexample/src
Alex Fu
7
Perpesanan benar-benar diperlukan hanya jika layanan Anda dapat dipanggil oleh aplikasi lain. Kalau tidak, Anda dapat tetap dengan Binder yang mengembalikan Anda referensi ke Layanan dan hanya memanggil metode publik itu.
type-a1pha
13
Anda seharusnya membuat pertanyaan dan kemudian membuat jawaban sendiri, bukan menjawab masalah pada pertanyaan. Contoh yang bagus;)
7hi4g0

Jawaban:

46

Lihat contoh LocalService .

Anda Servicemengembalikan instance dirinya kepada konsumen yang menelepon onBind. Kemudian Anda dapat langsung berinteraksi dengan layanan, misalnya mendaftarkan antarmuka pendengar Anda sendiri dengan layanan, sehingga Anda bisa mendapatkan panggilan balik.

Christopher Orr
sumber
2
Satu-satunya masalah dengan itu adalah bahwa itu tidak akan menggunakan Messenger, jadi itu tidak akan menjawab pertanyaan semu ini. Saya telah menggunakan Layanan Lokal, tetapi saya senang menemukan contoh Messenger / Handler. Saya tidak percaya Layanan Lokal dapat dimasukkan ke dalam proses lain.
Ben
@ Christoper-Orr: Saya sangat berterima kasih Anda telah memposting tautan Android BroadcastReceivertutorial itu. Saya telah menggunakan LocalBroadcastManageruntuk bertukar data secara terus menerus antara dua Activitycontoh.
Dirk
Masalahnya LocalBroadcastManageradalah non-pemblokiran dan Anda harus menunggu hasilnya. Terkadang Anda ingin hasil langsung.
TheRealChx101
Tolong bantu saya dengan pertanyaan ini stackoverflow.com/questions/51508046/…
Rajesh K
20

Untuk mengirim data ke layanan, Anda dapat menggunakan:

Intent intent = new Intent(getApplicationContext(), YourService.class);
intent.putExtra("SomeData","ItValue");
startService(intent);

Dan setelah dalam layanan di onStartCommand () dapatkan data dari maksud.

Untuk mengirim data atau acara dari layanan ke aplikasi (untuk satu atau lebih kegiatan):

private void sendBroadcastMessage(String intentFilterName, int arg1, String extraKey) {
    Intent intent = new Intent(intentFilterName);
    if (arg1 != -1 && extraKey != null) {
        intent.putExtra(extraKey, arg1);
    }
    sendBroadcast(intent);
}

Metode ini menelepon dari layanan Anda. Anda cukup mengirim data untuk Aktivitas Anda.

private void someTaskInYourService(){

    //For example you downloading from server 1000 files
    for(int i = 0; i < 1000; i++) {
        Thread.sleep(5000) // 5 seconds. Catch in try-catch block
        sendBroadCastMessage(Events.UPDATE_DOWNLOADING_PROGRESSBAR, i,0,"up_download_progress");
    }

Untuk menerima acara dengan data, buat dan daftarkan metode registerBroadcastReceivers () di aktivitas Anda:

private void registerBroadcastReceivers(){
    broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int arg1 = intent.getIntExtra("up_download_progress",0);
            progressBar.setProgress(arg1);
        }
    };
    IntentFilter progressfilter = new IntentFilter(Events.UPDATE_DOWNLOADING_PROGRESS);
    registerReceiver(broadcastReceiver,progressfilter);

Untuk mengirim lebih banyak data, Anda dapat memodifikasi metode sendBroadcastMessage();. Ingat: Anda harus mendaftarkan siaran di metode onResume () & batalkan pendaftaran di onStop ()!

MEMPERBARUI

Tolong jangan gunakan jenis komunikasi saya antara Aktivitas & Layanan. Ini cara yang salah. Untuk pengalaman yang lebih baik silakan gunakan lib khusus, seperti kami:

1) EventBus dari greenrobot

2) Otto dari Square Inc

PS Saya hanya menggunakan EventBus dari greenrobot di proyek saya,

hitam13
sumber
2
di mana saya harus mendaftarkan penerima di onResume dan di onStop yang dapat saya lakukan dalam aktivitas?
user3233280
Iya. Untuk menerima acara dari layanan, Anda harus mendaftar siaran di onResume. Ingatlah bahwa Anda harus membatalkan registrasi siaran di onStop. Sekarang, saya tidak merekomendasikan menggunakan metode saya. Silakan gunakan lib khusus untuk berkomunikasi dengan pandangan / kegiatan / layanan lain seperti EventBus github.com/greenrobot/EventBus atau Otto github.com/square/otto
a.black13
1
tolong bantu saya bagaimana saya bisa menggunakan ini saya terjebak dalam proyek saya dalam komunikasi layanan
user3233280
8
Apakah Google merekomendasikan hal ini, atau Anda hanya mengatakan itu "salah" karena Anda pikir solusi lain lebih baik?
Kevin Krumwiede
plus satu untuk menyediakan tautan ke EventBusdan Otto.
Mohammed Ali
14

Catatan: Anda tidak perlu memeriksa apakah layanan Anda berjalan CheckIfServiceIsRunning(),, karena bindService()akan memulainya jika tidak berjalan.

Juga: jika Anda memutar telepon Anda tidak ingin bindService()lagi, karena onCreate()akan dipanggil lagi. Pastikan untuk mendefinisikan onConfigurationChanged()untuk mencegah ini.

Seseorang disuatu tempat
sumber
Dalam kasus saya, saya tidak perlu layanan berjalan sepanjang waktu. Jika layanan sudah berjalan saat aktivitas dimulai, maka saya ingin mengikatnya. Jika layanan tidak berjalan saat aktivitas dimulai, saya ingin membiarkan layanan berhenti.
Lance Lefebure
1
Saya tidak yakin ini benar, bindService tidak memulai layanan, bisakah Anda arahkan ke dokumentasi?
Calin
1
developer.android.com/reference/android/app/Service.html Paragraf pertama menyatakanServices can be started with Context.startService() and Context.bindService()
Seseorang Di Suatu Tempat,
8
Message msg = Message.obtain(null, 2, 0, 0);
                    Bundle bundle = new Bundle();
                    bundle.putString("url", url);
                    bundle.putString("names", names);
                    bundle.putString("captions",captions); 
                    msg.setData(bundle);

Jadi Anda mengirimnya ke layanan. Setelah itu terima.

pengguna1964369
sumber
8

Semuanya baik-baik saja. Contoh activity/servicekomunikasi yang baik menggunakan Messenger .

Satu komentar: metode MyService.isRunning()ini tidak diperlukan .. bindService()dapat dilakukan beberapa kali. tidak ada salahnya itu.

Jika MyService berjalan dalam proses yang berbeda maka fungsi statis MyService.isRunning()akan selalu mengembalikan false. Jadi tidak perlu fungsi ini.

Ishank Gupta
sumber
2

Ini adalah bagaimana saya menerapkan Aktivitas-> Layanan Komunikasi: pada Kegiatan saya saya punya

private static class MyResultReciever extends ResultReceiver {
     /**
     * Create a new ResultReceive to receive results.  Your
     * {@link #onReceiveResult} method will be called from the thread running
     * <var>handler</var> if given, or from an arbitrary thread if null.
     *
     * @param handler
     */
     public MyResultReciever(Handler handler) {
         super(handler);
     }

     @Override
     protected void onReceiveResult(int resultCode, Bundle resultData) {
         if (resultCode == 100) {
             //dostuff
         }
     }

Dan kemudian saya menggunakan ini untuk memulai Layanan saya

protected void onCreate(Bundle savedInstanceState) {
MyResultReciever resultReciever = new MyResultReciever(handler);
        service = new Intent(this, MyService.class);
        service.putExtra("receiver", resultReciever);
        startService(service);
}

Dalam Layanan saya, saya punya

public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null)
        resultReceiver = intent.getParcelableExtra("receiver");
    return Service.START_STICKY;
}

Semoga ini membantu

ketrox
sumber
0

Menurut saya Anda dapat menyimpan sebagian memori dengan mendeklarasikan aktivitas Anda dengan "mengimplementasikan Handler.Callback"

Quasaur
sumber
0

Tutorial hebat, presentasi fantastis. Rapi, sederhana, pendek, dan sangat jelas. Meskipun, notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);metode tidak lebih. Seperti yang dinyatakan trante di sini , pendekatan yang baik adalah:

private static final int NOTIFICATION_ID = 45349;

private void showNotification() {
    NotificationCompat.Builder builder =
            new NotificationCompat.Builder(this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("My Notification Title")
                    .setContentText("Something interesting happened");

    Intent targetIntent = new Intent(this, MainActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(contentIntent);
    _nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    _nManager.notify(NOTIFICATION_ID, builder.build());
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (_timer != null) {_timer.cancel();}
    _counter=0;
    _nManager.cancel(NOTIFICATION_ID); // Cancel the persistent notification.
    Log.i("PlaybackService", "Service Stopped.");
    _isRunning = false;
}

Diperiksa sendiri, semuanya berfungsi seperti mantra (aktivitas dan nama layanan mungkin berbeda dari aslinya).

kulit hijau
sumber
0

Saya telah melihat semua jawaban. Saya ingin tahu cara paling kuat sekarang sehari . Itu akan membuat Anda berkomunikasi antara Activity - Service - Dialog - Fragments(Semuanya).

EventBus

Lib ini yang saya gunakan dalam proyek saya memiliki fitur hebat yang berkaitan dengan perpesanan.

EventBus dalam 3 langkah

  1. Tentukan acara:

    public static class MessageEvent { /* Additional fields if needed */ }

  2. Siapkan pelanggan:

Deklarasikan dan beri anotasi metode berlangganan Anda, tentukan secara spesifik mode utas :

@Subscribe(threadMode = ThreadMode.MAIN) 
public void onMessageEvent(MessageEvent event) {/* Do something */};

Daftarkan dan batalkan registrasi pelanggan Anda. Misalnya di Android, aktivitas dan fragmen biasanya harus mendaftar sesuai dengan siklus hidupnya:

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this);
}
  1. Posting acara:

    EventBus.getDefault().post(new MessageEvent());

Tambahkan saja dependensi ini di tingkat level aplikasi Anda

compile 'org.greenrobot:eventbus:3.1.1'
Khemraj
sumber