Pertanyaan Mengikat layanan ke aktivitas di Android


Saya mencoba menulis media player sederhana yang memainkan streaming audio menggunakan RTSP. Saya memiliki GUI-aktivitas dan layanan yang melakukan pemutaran. Pertanyaan saya adalah cara terbaik untuk berkomunikasi antara aktivitas dan layanan (mis. Memperbarui gui berdasarkan keadaan pemain).

Saya tahu bahwa saya dapat mengikat layanan ke aktivitas menggunakan onBind (), tetapi jika saya mengerti dengan benar ini akan menghentikan layanan jika aktivitas tersebut terbunuh. Saya ingin melanjutkan pemutaran bahkan jika pengguna keluar dari aktivitas. Apakah ada cara standar atau pilihan untuk menangani masalah ini?


75
2017-12-16 17:28


asal


Jawaban:


"Jika Anda memulai Layanan android dengan startService(..) Layanan itu akan tetap berjalan sampai Anda secara eksplisit memohon stopService(..). Ada dua alasan mengapa layanan dapat dijalankan oleh sistem. Jika seseorang menelepon Context.startService() maka sistem akan mengambil layanan (membuatnya dan memanggilnya onCreate() metode jika diperlukan) dan kemudian memanggilnya onStartCommand(Intent, int, int) metode dengan argumen yang diberikan oleh klien. Layanan akan pada titik ini terus berjalan hingga Context.stopService() atau stopSelf() disebut. Perhatikan bahwa beberapa panggilan ke Context.startService() jangan bersarang (meskipun mereka menghasilkan beberapa panggilan yang sesuai untuk onStartCommand()), jadi tidak peduli berapa kali dimulai, layanan akan dihentikan satu kali Context.stopService() atau stopSelf() disebut; Namun, layanan dapat menggunakan mereka stopSelf(int) metode untuk memastikan layanan tidak dihentikan sampai mulai niat telah diproses.

Klien juga bisa digunakan Context.bindService() untuk mendapatkan koneksi terus-menerus ke layanan. Ini juga menciptakan layanan jika belum berjalan (memanggil onCreate() saat melakukannya), tetapi tidak menelepon onStartCommand(). Klien akan menerima IBinder keberatan bahwa layanan tersebut kembali dari itu onBind(Intent) metode, memungkinkan klien untuk kemudian melakukan panggilan balik ke layanan. Layanan akan tetap berjalan selama koneksi telah dibuat (apakah klien tetap memiliki referensi di Layanan atau tidak IBinder). Biasanya itu IBinder kembali adalah untuk antarmuka kompleks yang telah ditulis dalam AIDL.

Layanan dapat dimulai dan memiliki koneksi yang terikat padanya. Dalam kasus seperti itu, sistem akan menjaga layanan berjalan selama baik itu dimulai atau ada satu atau lebih koneksi ke sana dengan Context.BIND_AUTO_CREATE bendera. Begitu tidak satu pun dari situasi ini berlaku, Layanan onDestroy() metode dipanggil dan layanan diakhiri secara efektif. Semua pembersihan (menghentikan utas, penerima yang tidak terdaftar) harus lengkap setelah kembali dari onDestroy(). "


139
2017-12-16 18:27



Pertama-tama, 2 hal yang perlu kita pahami

Klien

  • itu membuat permintaan ke server tertentu

    bindService(new 
        Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);`
    

sini mServiceConn adalah contoh dari ServiceConnection class (inbuilt) sebenarnya adalah antarmuka yang perlu kita implementasikan dengan dua metode (1 untuk jaringan terhubung dan jaringan kedua tidak terhubung) untuk memonitor status koneksi jaringan.

Server

  • Ini menangani permintaan klien dan membuat replika itu sendiri yang bersifat pribadi untuk klien saja yang mengirim permintaan dan replika server ini berjalan pada thread yang berbeda.

Sekarang di sisi klien, bagaimana cara mengakses semua metode server?

  • Server mengirim respons dengan objek IBind Object.so IBind adalah handler kami yang mengakses semua metode layanan dengan menggunakan operator (.).

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
        //binder comes from server to communicate with method's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

sekarang bagaimana memanggil metode yang ada dalam layanan

myservice.serviceMethod();

sini myService adalah objek dan serviceMethode adalah metode dalam layanan. Dan dengan cara ini komunikasi terjalin antara klien dan server.


20
2017-08-22 07:24



Saya mencoba menelepon

startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);

akibatnya dan saya bisa menciptakan layanan yang kaku dan mengikatnya. Tutorial terperinci untuk Contoh Layanan Terikat.


8
2018-05-09 16:08



Ada metode yang disebut unbindService yang akan mengambil ServiceConnection yang akan Anda buat saat memanggil bindService. Ini akan memungkinkan Anda untuk memutuskan sambungan dari layanan sementara tetap membiarkannya berjalan.

Ini mungkin menimbulkan masalah ketika Anda menghubungkannya lagi, karena Anda mungkin tidak tahu apakah itu berjalan atau tidak ketika Anda memulai aktivitas lagi, jadi Anda harus mempertimbangkan itu dalam kode aktivitas Anda.

Semoga berhasil!


5
2017-12-16 17:38



Ini adalah jawaban yang bias, tetapi saya menulis sebuah pustaka yang dapat menyederhanakan penggunaan Layanan Android, jika mereka berjalan secara lokal dalam proses yang sama dengan aplikasi: https://github.com/germnix/acacia

Pada dasarnya Anda mendefinisikan antarmuka yang dianotasikan dengan @Service dan kelas pelaksana, dan perpustakaan membuat dan mengikat layanan, menangani koneksi dan thread pekerja latar belakang:

@Service(ServiceImpl.class)
public interface MyService {
    void doProcessing(Foo aComplexParam);
}

public class ServiceImpl implements MyService {
    // your implementation
}

MyService service = Acacia.createService(context, MyService.class);
service.doProcessing(foo);

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    ...
    <service android:name="com.gmr.acacia.AcaciaService"/>
    ...
</application>

Anda bisa mendapatkan contoh dari android.app.Service terkait untuk menyembunyikan / menampilkan pemberitahuan terus-menerus, menggunakan android.app.Service Anda sendiri dan menangani threading secara manual jika Anda mau.


-1
2018-05-02 16:42



Jika pengguna mundur, onDestroy() metode akan dipanggil. Metode ini untuk menghentikan layanan apa pun yang digunakan dalam aplikasi. Jadi jika Anda ingin melanjutkan layanan meskipun pengguna mundur dari aplikasi, hapus saja onDestroy(). Semoga bantuan ini.


-4
2018-04-29 13:16