標籤:開啟 anr 原因 特點 ima -- 返回 set 注意
一. Service 介紹
Service屬於android四大組件之一,在很多地方經常被用到。開啟Service有兩種不同的方式:startService和bindService。不同的開啟方式,Service執行的生命週期方法也不同。
分 顯示/隱示調用 ,但是官網推薦用顯式的方式啟動Service。下面 service使用 用的就是顯示調用;注意事項用的就是隱示調用,在5.0系統上隱示調用會報錯。所以這裡只介紹使用顯示調用。
不能再service裡做耗時操作,否則ANR;需要開闢子線程進行耗時操作處理。
二.Service 使用 1.startService使用。
Intent intent = new Intent(this, TestService.class);
Log.w(Tag, "activity====啟動服務");
startService(intent);
執行效果:
Log.w(Tag, "activity====停止服務");stopService(intent);
執行效果:
2.bindService綁定.
private class MyConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { //只有當我們自己寫的MyService的onBind方法傳回值不為null時,才會被調用 Log.e("call", "onServiceConnected"); } @Override public void onServiceDisconnected(ComponentName name) { // 這個方法只有出現異常時才會調用,伺服器正常退出不會調用。 Log.e("call", "onServiceDisconnected"); } }
Log.w(Tag, "activity====綁定服務");
MyConnection conn = new MyConnection();//第一個參數:Intent意圖// 第二個參數:是一個介面,通過這個介面接收服務開啟或者停止的訊息,並且這個參數不能為null // 第三個參數:開啟服務時的操作,BIND_AUTO_CREATE代表自動建立service bindService(service, conn, BIND_AUTO_CREATE); bindService(intent, conn, BIND_AUTO_CREATE);
執行效果:
Log.w(Tag, "activity====解除綁定服務");
unbindService(conn);
執行效果:
3.區別:
以下摘自網路,後續驗證:
服務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啟動服務。這兩個方法都可以啟動Service,但是它們的使用場合有所不同。
使用startService()方法啟用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。使用bindService()方法啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。
如果打算採用Context.startService()方法啟動服務,在服務未被建立時,系統會先調用服務的onCreate()方法,接著調用onStart()方法。如果調用startService()方法前服務已經被建立,多次調用startService()方法並不會導致多次建立服務,但會導致多次調用onStart()方法。採用startService()方法啟動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。
如果打算採用Context.bindService()方法啟動服務,在服務未被建立時,系統會先調用服務的onCreate()方法,接著調用onBind()方法。這個時候調用者和服務綁定在一起,調用者退出了,系統就會先調用服務的onUnbind()方法,接著調用onDestroy()方法。如果調用bindService()方法前服務已經被綁定,多次調用bindService()方法並不會導致多次建立服務及綁定(也就是說onCreate()和onBind()方法並不會被多次調用)。如果調用者希望與正在綁定的服務解除綁定,可以調用unbindService()方法,調用該方法也會導致系統調用服務的onUnbind()-->onDestroy()方法。
三.Service 注意事項:
在5.0系統上使用如下方式start或者bind啟動service時候:
Intent intent = new Intent(); intent.setAction("com.example.user.firstapp.FIRST_SERVICE"); bindService(intent,coon,Service.BIND_AUTO_CREATE);
startService(intent);
android 5.0上,報錯:IllegalArgumentException: Service Intent must be explicit
原因是:Android5.0中service的intent一定要顯性聲明!!!
四.附上核心activity代碼:
package com.example.hp.testapp;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.TextView;import com.example.hp.testapp.service.TestService;import org.w3c.dom.Text;public class MainActivity extends AppCompatActivity implements View.OnClickListener { private String Tag = "TestServiceTag"; private TextView tv_btn_start; private TextView tv_btn_stop; private TextView tv_btn_bind; private TextView tv_btn_unbind; Intent intent; MyConnection conn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intent = new Intent(this, TestService.class); conn = new MyConnection(); initView(); initListener(); } private void initView() { tv_btn_start = (TextView) findViewById(R.id.tv_btn_start); tv_btn_stop = (TextView) findViewById(R.id.tv_btn_stop); tv_btn_bind = (TextView) findViewById(R.id.tv_btn_bind); tv_btn_unbind = (TextView) findViewById(R.id.tv_btn_unbind); } private void initListener() { tv_btn_start.setOnClickListener(this); tv_btn_stop.setOnClickListener(this); tv_btn_bind.setOnClickListener(this); tv_btn_unbind.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.tv_btn_start: /** * 啟動服務 */ Log.w(Tag, "activity====啟動服務"); startService(intent); break; case R.id.tv_btn_stop: /** * 停止服務 */ Log.w(Tag, "activity====停止服務"); stopService(intent); break; case R.id.tv_btn_bind: /** * 綁定服務 */ Log.w(Tag, "activity====綁定服務"); //第一個參數:Intent意圖 // 第二個參數:是一個介面,通過這個介面接收服務開啟或者停止的訊息,並且這個參數不能為null // 第三個參數:開啟服務時的操作,BIND_AUTO_CREATE代表自動建立service bindService(service, conn, BIND_AUTO_CREATE); bindService(intent, conn, BIND_AUTO_CREATE); break; case R.id.tv_btn_unbind: /** * 解除綁定服務 */ Log.w(Tag, "activity====解除綁定服務"); if (conn != null) { unbindService(conn); } default: break; } } @Override protected void onStart() { Log.w(Tag, "activity====onStart"); super.onStart(); } @Override protected void onRestart() { Log.w(Tag, "activity====onRestart"); super.onRestart(); } @Override public void onStateNotSaved() { Log.w(Tag, "activity====onStateNotSaved"); super.onStateNotSaved(); } @Override protected void onResume() { Log.w(Tag, "activity====onResume"); super.onResume(); } @Override protected void onPause() { Log.w(Tag, "activity====onPause"); super.onPause(); } @Override protected void onStop() { Log.w(Tag, "activity====onStop"); super.onStop(); } @Override protected void onDestroy() { Log.w(Tag, "activity====onDestroy"); super.onDestroy(); } private class MyConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { //只有當我們自己寫的MyService的onBind方法傳回值不為null時,才會被調用 Log.e("call", "onServiceConnected"); } @Override public void onServiceDisconnected(ComponentName name) { // 這個方法只有出現異常時才會調用,伺服器正常退出不會調用。 Log.e("call", "onServiceDisconnected"); } }}
Android 四大組件 (二) Service 使用