Service 定義(startService、bindService、IntentService)
Service:
是Android中實現程式後臺執行的解決方案。
定義為服務
Service預設並不會執行在子執行緒中,它也不會執行在一個獨立的程序中,它同樣執行在UI執行緒中,因此,不要在Service中執行耗時的操作,如果需要執行耗時的操作,可以在Service中建立子執行緒來完成耗時操作。
什麼是手機病毒?
手機病毒是編制者在手機程式中插入帶破壞資料。吸費。監控等功能的程式碼,能影響手機使用,能自我複製的一組指令或者程式程式碼。
病毒的共性是擁有潛伏性,觸發性,傳染性,破壞性。
病毒都是偷偷的在後臺執行預設的功能。
為什麼要用Service?
大部分病毒利用Service的特點,可以不知不覺(後臺)完成預設的功能。
作為Android工程師,至少需要了解Service是如何在後臺完成預設功能。
在真實的商業專案中都有定期在後臺執行任務(如:下載,上傳等)的需求。
當某個功能需要執行很長時間(如:下載,收集資料等),並且在執行過程中不需要讓使用者操作,不需要Activity進行互動的情況下,可以通過Service在後臺完成指定任務。
Service有幾種啟動模式?
有兩種啟動模式:
startService()啟動方式:主要用於執行後臺計算
bindService()啟動方式:主要用於和其它元件的互動
startService的特點及優缺點?
Service會經歷 onCreate –> onStart stopService的時候直接onDestroy
如果是 呼叫者直接退出而沒有呼叫stopService的話,Service會一直在後臺執行。 下次呼叫者再起來仍然可以stopService。
bindService 的特點及優缺點?
Service只會執行onCreate, 這個時候 呼叫者和Service繫結在一起
呼叫者退出了,Srevice就會呼叫onUnbind–>onDestroyed 所謂繫結在一起就共存亡了。
兩者放在一塊的程式碼演示:
package com.example.myapplication15;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_start;
private Button btn_end;
private Button bind;
private Button unbind;
private Button main;
private MyService.DownloadBinder downloadBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
downloadBinder = (MyService.DownloadBinder) iBinder;
downloadBinder.startDownload();
downloadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
DownLoadBinder downLoadBinder=new DownLoadBinder();
public class DownLoadBinder extends Binder{
public void startDownload(){}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start=findViewById(R.id.btn_start);
btn_end=findViewById(R.id.btn_end);
btn_start.setOnClickListener(this);
btn_end.setOnClickListener(this);
bind = findViewById(R.id.main_bind);
unbind = findViewById(R.id.main_unbind);
bind.setOnClickListener(this);
unbind.setOnClickListener(this);
main=findViewById(R.id.main2_btn);
main.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.main_bind:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);
break;
case R.id.main_unbind:
unbindService(connection);
break;
case R.id.btn_start:
Intent statintent=new Intent(MainActivity.this,MyService.class);
startService(statintent);
break;
case R.id.btn_end:
Intent endintent=new Intent(MainActivity.this,MyService.class);
stopService(endintent);
break;
case R.id.main2_btn:
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
default:
break;
}
}
}
佈局檔案:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.myapplication15.MainActivity">
<Button
android:text="開始"
android:layout_marginTop="50dp"
android:id="@+id/btn_start"
android:layout_gravity="center"
android:layout_width="80dp"
android:layout_height="50dp" />
<Button
android:text="結束"
android:layout_marginTop="50dp"
android:id="@+id/btn_end"
android:layout_gravity="center"
android:layout_width="80dp"
android:layout_height="50dp" />
<Button
android:id="@+id/main_bind"
android:text="繫結"
android:layout_marginTop="50dp"
android:layout_gravity="center"
android:layout_width="80dp"
android:layout_height="50dp" />
<Button
android:id="@+id/main_unbind"
android:text="解綁"
android:layout_marginTop="50dp"
android:layout_gravity="center"
android:layout_width="80dp"
android:layout_height="50dp" />
<Button
android:id="@+id/main2_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="轉到main2"/>
</LinearLayout>
寫一個類繼承service:
package com.example.myapplication15;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import static android.content.ContentValues.TAG;
public class MyService extends Service {
private DownloadBinder mBinder=new DownloadBinder();
class DownloadBinder extends Binder {
public void startDownload(){
Log.e(TAG, "MyService: "+"startDownload ");
}
public int getProgress(){
Log.e(TAG, "MyService: "+"getProgress ");
return 0;
}
}
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
Log.e("Myservice", "onCreate: executed" );
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Myservice", "onStartCommand: executed" );
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0;i<10;i++){
Log.e("Service"+ Thread.currentThread().getName(),i+"***" );
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("Myservice"+Thread.currentThread().getName() ,"onDestroy: executed" );
}
}
當點選開始的時候 log出如圖的效果:
當點選結束的時候:
當再次連續點選開始時,oncreate 只是被執行了一次。而onStartCommand可以被執行很多次:
當點選繫結的時候:
當點選解綁的時候 執行銷燬:
IntentService的特點及其優缺點?
1是一種服務,比較適合高優先順序的後臺任務
2.任務結束自動退出
3.IntentService是Service的子類,用來處理非同步請求,IntentService在onCreate()通過HandlerThread開啟一個執行緒