Android IPC機制ACtivity繫結Service通訊程式碼例項
阿新 • • 發佈:2020-09-29
Binder通訊過程類似於TCP/IP服務連線過程binder四大架構Server(伺服器),Client(客戶端),ServiceManager(DNS)以及Binder驅動(路由器)
其中Server,Client,ServiceManager運行於使用者空間,驅動運行於核心空間。這四個角色的關係和網際網路類似:Server是伺服器,Client是客戶終端,SMgr是域名伺服器(DNS),驅動是路由器。
book.java
package com.example.android_binder_testservice; import android.os.Parcel; import android.os.Parcelable; public class Book implements Parcelable { private String bookName; private String author; private int publishDate; public Book() { } public Book(String bookName,String author,int publishDate) { super(); this.bookName = bookName; this.author = author; this.publishDate = publishDate; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public int getPublishDate() { return publishDate; } public void setPublishDate(int publishDate) { this.publishDate = publishDate; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out,int flags) { out.writeString(bookName); out.writeString(author); out.writeInt(publishDate); } public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() { @Override public Book[] newArray(int size) { return new Book[size]; } @Override public Book createFromParcel(android.os.Parcel source) { return new Book(source); } }; public Book(Parcel in) { bookName = in.readString(); author = in.readString(); publishDate = in.readInt(); } }
上面是一個 實現了parcelable的實體類,就是將book序列化,在putExtra到Service時會被寫入記憶體加快程式速度
mainActivity.java
package com.example.android_binder_testservice; import android.os.Bundle; import android.util.Log; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { Button startServiceButton;// 啟動服務按鈕 Button shutDownServiceButton;// 關閉服務按鈕 Button startBindServiceButton;// 啟動繫結服務按鈕 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWidget(); regiestListener(); } public void getWidget(){ startServiceButton = (Button) findViewById(R.id.startService); startBindServiceButton = (Button) findViewById(R.id.bindService); shutDownServiceButton = (Button) findViewById(R.id.stopService); } public void regiestListener() { startServiceButton.setOnClickListener(startService); shutDownServiceButton.setOnClickListener(shutdownService); startBindServiceButton.setOnClickListener(startBinderService); } /** 啟動服務的事件監聽 */ public Button.OnClickListener startService = new Button.OnClickListener() { public void onClick(View view) { /** 單擊按鈕時啟動服務 */ Intent intent = new Intent(MainActivity.this,CountService.class); startService(intent); Log.v("MainStadyServics","start Service"); } }; /** 關閉服務 */ public Button.OnClickListener shutdownService = new Button.OnClickListener() { public void onClick(View view) { /** 單擊按鈕時啟動服務 */ Intent intent = new Intent(MainActivity.this,CountService.class); /** 退出Activity是,停止服務 */ stopService(intent); Log.v("MainStadyServics","shutDown serveice"); } }; /** 開啟繫結服務的Activity */ public Button.OnClickListener startBinderService = new Button.OnClickListener() { public void onClick(View view) { /** 單擊按鈕時啟動服務 */ Intent intent = new Intent(MainActivity.this,UseBrider.class); startActivity(intent); Log.v("MainStadyServics","start Binder Service"); } }; }
mainActivity中當使用startService()啟動Service時會呼叫Service的onStartCommand()
當使用bindService()則會呼叫onBind()方法,可能會覺了看的又看怎麼沒看到bindService()這個方法呢
重點在
Intent intent = new Intent(MainActivity.this,UseBrider.class);
startActivity(intent);
繼續上程式碼
UseBrider.java
/** 通過bindService和unBindSerivce的方式啟動和結束服務 */ public class UseBrider extends FragmentActivity { /** 引數設定 */ CountService countService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new UseBriderFace(this)); Intent intent = new Intent(UseBrider.this,CountService.class); intent.putExtra("book",new Book("name","an",1999)); /** 進入Activity開始服務 * conn */ bindService(intent,conn,Context.BIND_AUTO_CREATE); } private ServiceConnection conn = new ServiceConnection() { /* * 這個方法會獲取到CountService的onBind方法中返回的Binder物件 * 然後就可以對服務進行某種操作了 */ public void onServiceConnected(ComponentName name,IBinder service) { // TODO Auto-generated method stub countService = ((CountService.ServiceBinder) service).getService(); countService.callBack(); } /** 無法獲取到服務物件時的操作 */ public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub countService = null; } }; protected void onDestroy() { super.onDestroy(); this.unbindService(conn); Log.v("MainStadyServics","out"); } }
UseBriderFace.java
public class UseBriderFace extends View{ /**建立引數*/ public UseBriderFace(Context context){ super(context); } public void onDraw(Canvas canvas){ canvas.drawColor(Color.WHITE);//畫白色背景 /**繪製文字*/ Paint textPaint = new Paint(); textPaint.setColor(Color.RED); textPaint.setTextSize(30); canvas.drawText("使用繫結服務",10,30,textPaint); textPaint.setColor(Color.GREEN); textPaint.setTextSize(18); canvas.drawText("使用繫結服務後,這個Activity關閉後",20,60,textPaint); canvas.drawText("繫結的服務也會關閉",5,80,textPaint); } }
UseBriderFace.java類其實就是用java定義的佈局可以用xml檔案代替
countService.java
package com.example.android_binder_testservice; /**引入包*/ import android.app.Service;// 服務的類 import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; import android.os.Binder; import android.content.Intent; import android.util.Log; /** 計數的服務 */ public class CountService extends Service { private String TAG = CountService.class.getSimpleName(); /** 建立引數 */ boolean threadDisable; int count; Book book; /* * 當通過bindService()啟動CountService時會呼叫這個方法並返回一個ServiceBinder物件 * 這個Binder物件封裝著一個CountService例項, * 客戶端就可以通過ServiceBinder對服務端進行一些操作 */ public IBinder onBind(Intent intent) { Log.i(TAG,"onBind"); book = intent.getParcelableExtra("book"); return new ServiceBinder(); } @Override public int onStartCommand(Intent intent,int flags,int startId) { Log.i(TAG,"onStartCommand"); return super.onStartCommand(intent,flags,startId); } @Override public boolean onUnbind(Intent intent) { Log.i(TAG,"onUnbind"); return super.onUnbind(intent); } @Override public void onRebind(Intent intent) { Log.i(TAG,"onRebind"); super.onRebind(intent); } public void onCreate() { super.onCreate(); /** 建立一個執行緒,每秒計數器加一,並在控制檯進行Log輸出 */ new Thread(new Runnable() { public void run() { while (!threadDisable) { try { Thread.sleep(1000); } catch (InterruptedException e) { } count++; Log.v("CountService","Count is" + count); } } }).start(); Log.i(TAG,"onCreate"); } public void onDestroy() { super.onDestroy(); /** 服務停止時,終止計數程序 */ this.threadDisable = true; Log.i(TAG,"onDestroy"); } public int getConunt() { return count; } public void callBack(){ Log.i(TAG,"hello,i am a method of CountService"); } class ServiceBinder extends Binder { public CountService getService() { return CountService.this; } } }
程式碼解釋有了,想不出來了
原始碼下載地址:http://git.oschina.net/zwh_9527/Binder
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。