SDK Service线程详解.docx
《SDK Service线程详解.docx》由会员分享,可在线阅读,更多相关《SDK Service线程详解.docx(40页珍藏版)》请在冰豆网上搜索。
SDKService线程详解
SDKService线程详解
作者:
高焕堂
试阅:
publicTextViewtv,tv2;
privateIBinderib=null;
privateHandlerh1,h2;
publicvoidonCreate(Bundleicicle){
super.onCreate(icicle);
LinearLayoutlayout=newLinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
btn=newButton(this);
btn.setId(101);
btn.setText("createthreads");
btn.setBackgroundResource(R.drawable.heart);
btn.setOnClickListener(this);
LinearLayout.LayoutParamsparam=newLinearLayout.LayoutParams(120,50);
param.topMargin=10;
layout.addView(btn,param);
btn2=newButton(this);
btn2.setId(102);
btn2.setText("exit");
btn2.setBackgroundResource(R.drawable.heart);
btn2.setOnClickListener(this);
layout.addView(btn2,param);
tv=newTextView(this);
tv.setTextColor(Color.WHITE);
tv.setText("");
LinearLayout.LayoutParamsparam2=newLinearLayout.LayoutParams(FP,WC);
param2.topMargin=10;
layout.addView(tv,param2);
tv2=newTextView(this);
tv2.setTextColor(Color.WHITE);
tv2.setText("");
layout.addView(tv2,param2);
setContentView(layout);
//-----------------------------------------------------
Intentin=newIntent("com.misoo.kx02c.REMOTE_SERVICE");
in.putExtra("key",0);
bindService(in,mConnection,Context.BIND_AUTO_CREATE);
}
privateServiceConnectionmConnection=newServiceConnection(){
publicvoidonServiceConnected(ComponentNameclassName,IBinderibinder){
ib=ibinder;
}
publicvoidonServiceDisconnected(ComponentNameclassName){}
};
publicvoidonClick(Viewv){
switch(v.getId()){
case101:
h1=newHandler(){
publicvoidhandleMessage(Messagemsg){
tv.setText((String)msg.obj);
}};
Threadt1=newThread(newTask());
正文:
l 由进程(Process)的主线程(Mainthread)执行SDK-Service(如下图的myService)对象。
● Android底层BinderSystem在binding-time会从该进程的Threadpool里启动一个线程来执行SDK-Service的Binder接口对象(如myBinder)。
● 执行myActivity对象的线程与myBinder对象的线程会同步(Synchronize),让myActivity开发者觉得IPC远程呼叫、跨进程的两个线程,就如同单一线程一般。
本文就LocalSDK-Service与RemoteSDK-Service两种来说明之。
一、如果属于LocalService。
----则myActivity与myService两者都是由mainthread所执行。
亦即,两者是同一线程所执行。
此情形下,两个类别里的函数都不宜太费时(例如不宜超过5秒钟);但必要时可诞生子线程去执行费时的函数。
//ac01.java(myActivity)
packagecom.misoo.kx02b;
importandroid.app.Activity;
importandroid.content.Intent;
importandroid.graphics.Color;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
publicclassac01extendsActivityimplementsOnClickListener{
//privatefinalintWC=LinearLayout.LayoutParams.WRAP_CONTENT;
privateTextViewtx;
privateButtonbtn;
@OverridepublicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayoutlayout=newLinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParamsparam=
newLinearLayout.LayoutParams(150,40);
param.topMargin=5;
tx=newTextView(this);
tx.setTextSize(16);
tx.setTextColor(Color.BLUE);
tx.setBackgroundResource(R.drawable.x_yellow);
layout.addView(tx,param);
btn=newButton(this);
btn.setText("Exit");
btn.setBackgroundResource(R.drawable.earth);
btn.setOnClickListener(this);
layout.addView(btn,param);
this.setContentView(layout);
//--------------------------------------------------
Stringtna=Thread.currentThread().getName();
Thread.currentThread().setName(tna+"-myActivity");
//--------------------------------------------------
myService.setUpdateListener(newUpdateUIListener());
Intentsvc=newIntent(this,myService.class);
startService(svc);
}
@OverrideprotectedvoidonDestroy(){
super.onDestroy();{
Intentsvc=newIntent(this,myService.class);
stopService(svc);
}
}
classUpdateUIListenerimplementsIListener{
publicvoidupdate(Strings){
tx.setText(s);
}
}
publicvoidonClick(Viewv){
this.finish();
}
}
IListener.java
packagecom.misoo.kx02b;
publicinterfaceIListener{
publicvoidupdate(Strings);
}
//myService.java
packagecom.misoo.kx02b;
importjava.util.Timer;
importjava.util.TimerTask;
importandroid.app.Service;
importandroid.content.Intent;
importandroid.os.Handler;
importandroid.os.IBinder;
importandroid.os.Message;
publicclassmyServiceextendsService{
privatestaticIListenerplis;
privatestaticintk=0;
privateTimertimer=newTimer();
privateStringtna;
publicHandlerhandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
plis.update(tna);
}
};
@Override
publicvoidonCreate(){
super.onCreate();
tna=Thread.currentThread().getName();
TimerTasktask=newTimerTask(){
@Override
publicvoidrun(){
handler.sendEmptyMessage(0);
}
};
timer.schedule(task,1000,4000);
}
@Override
publicIBinderonBind(Intentintent){
returnnull;
}
publicstaticvoidsetUpdateListener(IListenerlistener){
plis=listener;
}
}
此程序输出:
此结果说明了,myActivity与myService两者都是由mainthread所执行。
二.
就一个SDKService而言,都是由mainthread执行myService的onCreate()、onBind()、onStart()等函数。
然而,是由独立的线程来执行myBinder:
:
onTransact()函数。
因为BinderSystem会从该进程的Threadpool里启动一个线程来执行SDK-Service的Binder接口对象(如myBinder)。
二、 如果属于RemoteService。
----则myActivity与myService各在不同进程里执行,两者都是由各进程的mainthread所执行。
亦即,两者是由不同的线程所执行。
此情形下,两个类别里的函数也不宜太费时(例如不宜超过5秒钟);但必要时可诞生子线程去执行较费时的函数。
----所以由mainthread(myService所在的进程的mainthread)执行
myService:
:
onCreate()、myBinder:
:
myBinder()和myService:
:
onBind()。
----在Binding-time时,BinderSystem会建立myActivity与myBinder(即myService的Interface)之间的连结(Connection)。
----在IPCcalling-time时,myActivity的线程与myBinder的线程会同步(Synchronize),让myActivity开发者觉得IPC远程呼叫、跨进程的两个线程,就如同单一线程一般。
----在送出IPCcall时,执行myBinder对象的线程会执行myBinder:
:
onTransact()函数。
兹写个程序来说明之,此程序执行时,出现下述画面:
按下上一个Button,显示出mainthread的执行路径:
按下第二个Button,显示出mainthread执行onBind()函数:
按下第三个Button,显示出BinderSystem启用独立的thread执行onTransact()函数:
兹列出程序代码如下:
//AndroidManifest.xml
xmlversion="1.0"encoding="utf-8"?
>
android="
package="com.misoo.kx02c">
icon="@drawable/icon">
name=".ac01"android:
label="@string/app_name">
name="android.intent.action.MAIN"/>
name="android.intent.category.LAUNCHER"/>
name=".myActivity"android:
process=":
remote">
name=".myService"android:
process=":
remote">
name="com.misoo.kx02c.REMOTE_SERVICE"/>
//ac01.java
packagecom.misoo.kx02c;
importandroid.app.Activity;
importandroid.content.ComponentName;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.ServiceConnection;
importandroid.graphics.Color;
importandroid.os.Bundle;
importandroid.os.IBinder;
importandroid.os.Parcel;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
publicclassac01extendsActivityimplementsOnClickListener{
privatefinalintWC=LinearLayout.LayoutParams.WRAP_CONTENT;
privatefinalintFP=LinearLayout.LayoutParams.FILL_PARENT;
privateButtonbtn,btn2,btn3,btn4;
publicTextViewtv;
privateIBinderib=null;
publicvoidonCreate(Bundleicicle){
super.onCreate(icicle);
LinearLayoutlayout=newLinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
btn=newButton(this);
btn.setId(101);
btn.setText("startservice");
btn.setBackgroundResource(R.drawable.heart);
btn.setOnClickListener(this);
LinearLayout.LayoutParamsparam=newLinearLayout.LayoutParams(120,50);
param.topMargin=10;
layout.addView(btn,param);
btn2=newButton(this);
btn2.setId(102);
btn2.setText("bindservice");
btn2.setBackgroundResource(R.drawable.heart);
btn2.setOnClickListener(this);
layout.addView(btn2,param);
btn3=newButton(this);
btn3.setId(103);
btn3.setText("IPCcall");
btn3.setBackgroundResource(R.drawable.heart);
btn3.setOnClickListener(this);
layout.addView(btn3,param);
btn4=newButton(this);
btn4.setId(104);
btn4.setText("exit");
btn4.setBackgroundResource(R.drawable.heart);
btn4.setOnClickListener(this);
layout.addView(btn4,param);
tv=newTextView(this);
tv.setTextColor(Color.WHITE);
tv.setText("");
LinearLayout.LayoutParamsparam2=newLinearLayout.LayoutParams(FP,WC);
param2.topMargin=10;
layout.addView(tv,param2);
setContentView(layout);
//-----------------------------------------------------
Stringtna=Thread.currentThread().getName();
Thread.currentThread().setName(tna+"-ac01");
//-----------------------------------------------------
}
privateServiceConnectionmConnection=newServiceConnection(){
publicvoidonServiceConnected(ComponentNameclassName,IBinderibinder){
ib=ibinder;
}
publicvoidonServiceDisconnected(ComponentNameclassName){}
};
publicvoidonClick(Viewv){
switch(v.getId()){
case101:
startService(newIntent("com.misoo.kx02c.REMOTE_SERVICE"));
break;
case102:
bindService(newIntent("com.misoo.kx02c.REMOTE_SERVICE"),
mConnection,Context.BIND_AUTO_CREATE);
break;
case103:
Parcelpc=Parcel.obtain();
Parcelpc_reply=Parcel.obtain();
try{
ib.transact(1,pc,pc_reply,0);
tv.setText(pc_reply.readString())