Pengalaman pertama perkhidmatan


Pengenalan kepada bahagian ini

Baiklah, kami telah mengkaji dan mengkaji Aktiviti dalam Android dalam tiga bahagian pertama, saya percaya semua orang telah mendapat banyak manfaat. Pada permulaan bahagian ini, kami terus mempelajari komponen kedua dalam Android: Perkhidmatan (Perkhidmatan), Okay, tanpa berlengah lagi, mari mulakan bahagian ini!


1. Konsep yang berkaitan dengan utas

Sebelum kita mula mempelajari Perkhidmatan, mari kita fahami beberapa konsep utas!

1) Konsep berkaitan:

  • Program : ditulis dalam bahasa tertentu untuk melengkapkan tugas khusus Satu set arahan (satu set kod statik)
  • proses: menjalankan program, penjadualan sistem dan peruntukan sumberUnit bebas, sistem pengendalian akan Peruntukkan ruang memori untuk setiap proses! Program ini dilaksanakan secara dinamik secara berurutan, mengalami pemuatan dan pelaksanaan kod, Proses lengkap dilaksanakan!
  • Benang: unit pelaksanaan yang lebih kecil daripada proses Setiap proses mungkin mempunyai berbilang utas Benang perlu diletakkan dalam proses Untuk. laksanakan, urutan diuruskan oleh program dan proses dijadualkan oleh sistem !
  • Pemahaman berbilang benang: Laksanakan berbilang arahan secara selari dan peruntukkan potongan masa CPU kepada setiap satu mengikut algoritma penjadualan Benang sebenarnya dilaksanakan dalam perkongsian masa , tetapi masa penukaran adalah sangat singkat dan pengguna berasa "secara serentak"!

2) Kitaran hayat benang:

1.png

3 ) Tiga cara untuk mencipta urutan:

  1. Warisi kelas Thread
  2. Laksanakan antara muka Runnable
  3. Laksanakan antara muka Boleh Panggil Jika anda menggunakan utas yang dicipta oleh 2, anda boleh memulakannya terus seperti ini:
    new Thread(myThread).start();
    Lebih kerap, kami suka menggunakan kelas tanpa nama, yang ditulis dalam perkara berikut cara:
    new Thread(new Runnable(){
         public void run();
             }).start();

2 Perbezaan antara Servis dan Thread

Sebenarnya mereka tidak berkait rapat, tetapi ramai rakan sering mengelirukan. dua. Thread ialah utas, unit terkecil pelaksanaan program, dan unit asas peruntukan CPU! Perkhidmatan ialah komponen yang disediakan oleh Android yang membolehkannya kekal di latar belakang untuk masa yang lama Penggunaannya adalah untuk melakukan operasi pengundian! Atau anda ingin melakukan sesuatu di latar belakang, seperti memuat turun kemas kini di latar belakang! Ingat untuk tidak mengelirukan kedua-dua konsep ini!


3. Gambarajah kitaran hayat perkhidmatan

2.png


4 kitaran hayat dalam gambar di atas, kita boleh tahu bahawa terdapat dua cara untuk menggunakan Perkhidmatan dalam Android:

1) StartService() memulakan Perkhidmatan
2) BindService() memulakan Perkhidmatan
PS: Terdapat cara lain, selepas memulakan Perkhidmatan, ikat Perkhidmatan Pesanan!


1) Penjelasan terperinci tentang kaedah yang berkaitan:

  • onCreate(): Panggilan balik sejurus selepas Perkhidmatan dibuat untuk kali pertama Kaedah ini, kaedah ini sepanjang kitaran hayat hanya akan dipanggil mengikut urutan!
  • onDestory(): Kaedah ini akan dipanggil semula apabila Perkhidmatan ditutup. Kaedah ini hanya akan dipanggil semula sekali.
  • onStartCommand(intent,flag,startId): Versi awal ialah onStart(intent,startId), Apabila pelanggan memanggil kaedah startService(Intent), ia akan dipanggil semula Kaedah StartService boleh dipanggil beberapa kali. Tetapi tiada objek Perkhidmatan baharu akan dibuat, tetapi objek Perkhidmatan yang dijana sebelum ini akan terus digunakan semula, tetapi panggilan balik akan diteruskan. kaedah onStartCommand()!
  • IBinder onOnbind(intent): Kaedah ini adalah kaedah yang mesti dilaksanakan oleh Perkhidmatan Kaedah ini akan mengembalikan a Objek IBinder, aplikasi berkomunikasi dengan komponen Perkhidmatan melalui objek ini!
  • onUnbind(intent): Kaedah ini akan dipanggil semula apabila semua pelanggan yang terikat dengan Perkhidmatan diputuskan sambungan!

2) StartService memulakan Perkhidmatan

Permulaan pertama akan mencipta contoh Perkhidmatan, memanggil onCreate() dan kaedah onStartCommand(), Perkhidmatan pada masa ini Memasuki keadaan berjalan, jika StartService dipanggil semula untuk memulakan Perkhidmatan, tiada objek Perkhidmatan baharu akan dibuat. Sistem akan terus menggunakan semula objek Perkhidmatan yang dibuat sebelum ini dan memanggil kaedah onStartCommand()nya!
Tetapi Perkhidmatan sedemikian tidak mempunyai sambungan yang diperlukan dengan pemanggilnya, maksudnya, apabila pemanggil menamatkan kitaran hayatnya, Tetapi selagi stopService tidak dipanggil, Perkhidmatan akan terus berjalan
Tidak kira berapa kali Perkhidmatan dimulakan, Perkhidmatan hanya perlu dipanggil sekali untuk menghentikan Perkhidmatan<🎜! >


3) BindService memulakan Perkhidmatan

Apabila bindService digunakan untuk mengikat Perkhidmatan buat kali pertama, sistem akan membuat contoh Perkhidmatan dan memanggil kaedah onCreate() dan onBind()nya, dan kemudian pemanggil boleh berinteraksi dengan Perkhidmatan melalui IBinder Jika bindService digunakan semula untuk mengikat Perkhidmatan, sistem tidak akan mencipta contoh Perkhidmatan baharu, begitu juga onBind() kaedah dipanggil semula , hanya akan menghantar objek IBinder terus kepada pelanggan lain yang ditambahkan kemudian!
Jika kami menyahikat perkhidmatan, kami hanya perlu memanggil unbindService(), pada masa itu onUnbind dan kaedah onDestory akan Dipanggil! Ini adalah situasi klien Jika berbilang pelanggan terikat kepada Perkhidmatan yang sama, keadaannya adalah seperti berikut Apabila pelanggan melengkapkan interaksinya dengan perkhidmatan, ia memanggil kaedah unbindService() untuk menyahikatnya. Apabila semua pelanggan tidak terikat daripada perkhidmatan, sistem akan memusnahkan perkhidmatan. (Melainkan perkhidmatan juga dimulakan dengan kaedah startService())
Selain itu, tidak seperti situasi di atas, Perkhidmatan dalam mod bindService berkaitan dengan pemanggil, yang boleh difahami sebagai "Belalang di atas tali", mereka akan mati bersama-sama Selepas bindService, sebaik sahaja pemanggil dimusnahkan, Perkhidmatan akan ditamatkan serta-merta
Analisis bindService of Context dipanggil apabila memanggil Service melalui BindService bindService ( Intent Service, ServiceConnection conn, int flags)
service: Tentukan Perkhidmatan yang akan dimulakan melalui niat ini
conn: ServiceConnection objek, pengguna memantau hubungan antara pelawat dan status sambungan Perkhidmatan, Kaedah onServiceConnected(ComponentName,IBinder) dalam objek dipanggil semula apabila sambungan berjaya; Jika hos di mana Perkhidmatan terletak ditamatkan kerana penamatan tidak normal atau sebab lain, Perkhidmatan akan diputuskan sambungan daripada pelawat. Memanggil kaedah onServiceDisconnected(CompanentName) semasa menyambung, secara aktif memutuskan sambungan melalui kaedah unBindService() tidak akan memanggil kaedah di atas!
bendera: Tentukan sama ada untuk membuat Perkhidmatan secara automatik apabila mengikat (jika Perkhidmatan belum dibuat lagi), Parameter boleh menjadi 0 (tiada penciptaan automatik), BIND_AUTO_CREATE (penciptaan automatik)


4) BindService selepas StartService memulakan Perkhidmatan

Jika Perkhidmatan telah dimulakan oleh pelanggan melalui StartService(), maka ia akan dimulakan oleh pelanggan lain Kemudian panggil bindService() untuk mengikat kepada Perkhidmatan, kemudian panggil unbindService() untuk menyahikat dan akhirnya Jika bindService() dipanggil untuk mengikat kepada Perkhidmatan, kaedah kitaran hayat yang dicetuskan pada masa ini adalah seperti berikut:
onCreate( )->onStartCommand( )->onBind( )->onUnbind( ) -> onRebind( )
PS:Premisnya ialah: kaedah onUnbind() kembali benar!!! Sesetengah pembaca mungkin mempunyai keraguan di sini. Bukankah Perkhidmatan perlu dipanggil selepas memanggil unbindService? onDistory() sebenarnya, ini kerana Perkhidmatan ini dimulakan oleh StartService kami , jadi jika anda memanggil kaedah onUnbind() untuk menyahikat, Perkhidmatan tidak akan ditamatkan
Kesimpulan: Jika kami menggunakan bindService untuk mengikat Perkhidmatan yang dimulakan, ambil perhatian bahawa ia telah dimulakan !!! Sistem hanya menghantar objek IBinder dalaman Perkhidmatan kepada Aktiviti dan tidak memindahkan kitaran hayat Perkhidmatan. Ia terikat kepada Aktiviti, jadi apabila kaedah unBindService() dipanggil untuk menyahikat, Perkhidmatan tidak akan dimusnahkan!


5. Pengesahan kitaran hayat

Seterusnya kami menulis kod untuk mengesahkan kitaran hayat:

1) Sahkan urutan panggilan StartService untuk memulakan Perkhidmatan

Mula-mula kami menyesuaikan Perkhidmatan, menulis semula kaedah yang berkaitan dan pengguna mencetak pengesahan pada logcat:

TestService1.java

TestService1 kelas awam melanjutkan Perkhidmatan {
TAG String akhir peribadi = "TestService1";
//Kaedah yang mesti dilaksanakan
@Override
public IBinder onBind(Niat dalam khemah) {
Log.i(TAG, "kaedah onBind dipanggil!");
kembalikan nol; public void onCreate() {
Log.i(TAG, "onCreate method is called!");
super.onCreate();
}

// Dipanggil apabila Perkhidmatan dimulakan
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand method was called!"); return super.onStartCommand (niat, flags ,startId); Telah dipanggil!

AndroidManifest.xml melengkapkan pendaftaran Perkhidmatan


<!-- Konfigurasikan komponen Perkhidmatan dan konfigurasikan tindakan pada masa yang sama -->
<perkhidmatan android:name=".TestService1">                                                                                                                                                                                                                                               , dan akhirnya penulisan MainActivity, memanggil startService( ) dan stopService( ) masing-masing dalam acara klik butang

kelas awam MainActivity melanjutkan Aktiviti {

Butang peribadi mula; Butang peribadi berhenti;
@Override
dilindungi void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); (Button) findViewById(R.id.btnstart);
stop = (Button) findViewById(R.id.btnstop); //Buat In yang memulakan khemah Perkhidmatan dan atribut Niat
akhir Intent intent = new Intent();
intent.setAction("com.jay.example.service.TEST_SERVICE1");
//Tetapkan acara klik untuk dua butang, masing-masing mula Hentikan perkhidmatan
mula. setOnClickListener(OnClickListener() baharu {
@Override
public void onClick(Lihat v) {
           startService(niat);                                      }  
        });  

stop.setOnclickListener (onClickListener baru () { @Override
public void onClick (view v) {
stopservice (intent);     }  
}


Tangkapan skrin sedang berjalan:

3.jpg

Klik untuk memulakan perkhidmatan:

4.jpg

Saya kenyang dan tiada apa-apa nak buat, jadi saya akan memesan beberapa lagi:

5.jpg

Klik terakhir untuk menghentikan perkhidmatan:

6.jpg

Analisis keputusan:

Daripada keputusan berjalan di atas, kami boleh mengesahkan apa yang dijelaskan dalam rajah kitaran hayat kami: Kami mendapati bahawa kaedah onBind() tidak dipanggil Selain itu, mengklik untuk memulakan Perkhidmatan beberapa kali hanya akan memanggil onStartCommand berulang kali. Kaedah! Tidak kira berapa kali kami memulakan Perkhidmatan, stopService akan menghentikan Perkhidmatan


2) Sahkan urutan di mana BindService memulakan Perkhidmatan:

Sebelum kami mula menulis kod, kita mesti terlebih dahulu Mari belajar beberapa perkara dahulu: Yang pertama ialah kaedah Konteks bindService yang diberikan di bawah gambaran besar pertama:

  • Objek ServiceConnection: memantau sambungan antara pelawat dan Perkhidmatan Jika sambungan berjaya, panggil balik onServiceConnected(), jika penamatan tidak normal atau sebab lain menyebabkan Perkhidmatan terputus sambungan daripada pelawat Apabila disambungkan, kaedah onServiceDisconnected dipanggil semula Memanggil unBindService() tidak akan memanggil kaedah ini
  • Terdapat objek IBinder dalam kaedah onServiceConnected, yang boleh melaksanakan Perkhidmatan terikat. komunikasi antara satu sama lain! Apabila kita membangunkan kelas Perkhidmatan, kita perlu melaksanakan kaedah IBinder onBind() secara lalai, yang kembali Objek IBinder akan dihantar ke parameter onServiceConnected dalam objek ServiceConnection, dan kita boleh Berkomunikasi dengan Perkhidmatan melalui IBinder ini di sini

Ringkasan:
Langkah 1:Warisi Pengikat dalam Perkhidmatan tersuai , laksanakan anda objek IBinder sendiri
Langkah 2:Kembalikan objek IBinder anda sendiri melalui kaedah onBind()
Langkah 3:Tentukan satu dalam kelas yang mengikat objek Service ServiceConnection, mengatasi dua kaedah, onServiceConnected dan onDisconnected! Kemudian cuma baca parameter yang diluluskan oleh IBinder secara langsung

Nah, langkah seterusnya ialah menulis kod untuk mengesahkan Di sini kami menentukan Perkhidmatan untuk pemasaan. Kemudian mari tunjukkan penggunaan BindService dan proses memanggil kaedah Kod ini agak mudah dan tidak akan dijelaskan!

TestService2 kelas awam memanjangkan Perkhidmatan {
TAG String akhir persendirian = "TestService2";
bilangan int peribadi;

//Tentukan kaedah onBinder objek
pengikat MyBinder peribadi = MyBinder baharu();
MyBinder kelas awam memanjangkan Pengikat
{
public int getCount()
{ >          kiraan pulangan;                                          🎜> }  
 
//Kaedah yang mesti dilaksanakan, kaedah ini akan dipanggil semula apabila Perkhidmatan terikat untuk berubah  
 @Override  
 public IBinder onBind(Intent intent) {  
            Log.i(TAG, " onBind method is dipanggil!");
return binder;
}

//Panggil balik apabila Perkhidmatan dibuat
@Override
public void onCreate() {
Super. onCreate() ;
Log.i(TAG, "kaedah onCreate dipanggil!");
                                                                                                                                                                                                                                                                                                                                        {
                                      Benang.sleep(1000);                                                              kira++;
                                                                                           ;                                                                                                                                                                                                                                                                 Log.i(TAG, "on Unbind method Called!"); //Panggil balik sebelum Perkhidmatan ditutup
@Override
public void onDestroy() {
        super.onDestroy( );
this.quit = true;
Log.i(TAG, "onDestroyed kaedah dipanggil!");
}
@Override
public void onRe bind(Intent intent ) {
Log.i(TAG, "onRebind method is called!");
super .onRebind(niat);
} }
}

Daftar komponen Perkhidmatan dalam AndroidManifest.xml:

<service android:name=".TestService2" android:exported="false"> gt;

MainActivity.java:

Aktiviti Utama kelas awam memanjangkan Aktiviti {

Butang peribadi btnbind;
Butang peribadi btncel;
Butang peribadi btnstatus; , semasa mentakrifkan objek ServiceConnection
TestService2.MyBinder binder;
private ServiceConnection conn = new ServiceConnection() {

// Kaedah ini dipanggil semula apabila Aktiviti memutuskan sambungan daripada Perkhidmatan
        @ Override 🎜> public void onServiceDisconnected(ComponentName name) {
System.out.println("------Service Disconnected------");
}

//Ini kaedah dipanggil semula apabila sambungan antara Aktiviti dan Perkhidmatan berjaya
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("------Service. Bersambung-- -----");
binder = (TestService2.MyBinder) perkhidmatan;
}
};

@Override
protected void onCre ate(Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnbind = (Butang) findViewById(R.id.btnbind); (R.id .btncacel);
btnstatus = (Button) findViewById(R.id.btnstatus);        Niat akhir = Niat baharu();  
        intent.setAction("com.jay.example.service.TEST_SERVICE2");  
btnbind.setonClickListener (onClickListener baru () {
@Override
public void onClick (view v) {
// 绑定 service
bindService (niat, conn, conn, service.bind_auto_create);
            }  
        });   @Override
public void onClick (view v) { // 解除 解除 绑定
unbindservice (conn);
            }  
        });   @Override
public void onClick (view v) {
toast.makeText (getApplicationContext (), "perkhidmatan 的 的 值 为: "  
+ binder.getCount(), Toast.LENGTH_SHORT).show(); 🎜>



Klik untuk mengunci Perkhidmatan:

7.jpg

Teruskan klik kunci: tiada perubahan

8.jpg

Dapatkan status Perkhidmatan semasa:

9.jpg

Tidak Terikat:

10.jpg

Jika kami mengikat semula Jika anda menutup Aktiviti terus selepas tetapan, ralat akan dilaporkan. Kemudian kaedah onUnbind dan onDestory akan dipanggil secara automatik!

11.jpg Daripada keputusan berjalan di atas, ia disahkan bahawa dalam rajah kitaran hayat:

Gunakan BindService untuk mengikat Perkhidmatan, untuk memanggil kaedah onCreate(), onBind(), Kita boleh mengembalikan objek IBinder tersuai dalam kaedah onBind() dan kemudian memanggil Kaedah onServiceConnected() ServiceConnection boleh diperolehi dalam kaedah ini. Objek IBinder untuk melaksanakan operasi berkaitan; ia akan dipanggil secara automatik apabila Perkhidmatan tidak terikat kaedah onUnbind dan onDestroyed, sudah tentu, jika berbilang pelanggan terikat, semuanya perlu dinyahsekat Hanya pengikatan akan memanggil kaedah onDestoryed untuk pemusnahan!

12.jpg