安卓用于组件传递参数的对象是_入门篇:7.组件2:Android Service-service的数据传递与通信...
(由于對java的回調(diào)機(jī)制和線程理解的不夠透徹,所以這塊內(nèi)容我理解了好久,尤其是綁定服務(wù)傳遞數(shù)據(jù),一句一句寫一句一句看,對我來說挺難理解的。以后還要多看幾遍--!)
既然單純的啟動或跳轉(zhuǎn)activity沒有意義,那么同樣的,單純的啟動或綁定service也是無意義的,實(shí)際應(yīng)用中常常要攜帶數(shù)據(jù)啟動service或綁定service。
1.啟動service并傳遞數(shù)據(jù)
(1)新建一個Service:MyService
(2)在布局中添加兩個按鈕,啟動服務(wù)和停止服務(wù),和一個EditText,用戶傳遞數(shù)據(jù)
(3)給兩個按鈕添加監(jiān)聽器,分別執(zhí)行startService方法和stopService方法
(4)在MyService類中onCreate方法添加一個控制臺輸出語句,便于我們看到服務(wù)的狀態(tài)和數(shù)據(jù)的傳遞效果。
(5)在開始按鈕的onClick方法中添加intent.putExtra("data",etData.getText().toString()),用于在activity中初始化和傳遞數(shù)據(jù)。
(6)在MyService類中重寫onStartCommand方法,其中的intent參數(shù)用于接收activity傳來的數(shù)據(jù)。intent.getStringExtra("data");
此時運(yùn)行程序,點(diǎn)擊啟動服務(wù),會在控制臺輸出界面輸入框中的數(shù)據(jù),更改數(shù)據(jù)再次點(diǎn)擊啟動服務(wù),控制臺輸出的數(shù)據(jù)也隨之改變。點(diǎn)擊停止服務(wù),控制臺停止輸出。
代碼如下:
MyService.java:
public class MyService extendsService {private boolean running = false;private String data = "這是默認(rèn)信息";publicMyService() {
}
@OverridepublicIBinder onBind(Intent intent) {//TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Overridepublic int onStartCommand(Intent intent, int flags, intstartId) {
data= intent.getStringExtra("data");return super.onStartCommand(intent, flags, startId);
}
@Overridepublic voidonCreate() {super.onCreate();
running= true;newThread() {
@Overridepublic voidrun() {super.run();while(running){
System.out.println(data);try{
sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
@Overridepublic voidonDestroy() {super.onDestroy();
running= false;
}
}
MainActivity.java:
importandroid.os.Bundle;importandroid.support.v7.widget.SwitchCompat;importandroid.view.View;importandroid.widget.EditText;importlayout.MyService;public class MainActivity extends AppCompatActivity implementsView.OnClickListener{privateEditText etData;
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnStartSevice).setOnClickListener(this);
findViewById(R.id.btnStopSevice).setOnClickListener(this);
etData=(EditText) findViewById(R.id.etData);
}
@Overridepublic voidonClick(View view) {switch(view.getId()) {caseR.id.btnStartSevice:
Intent i= new Intent(this, MyService.class);
i.putExtra("data",etData.getText().toString());
startService(i);break;caseR.id.btnStopSevice:
stopService(new Intent(this,MyService.class));break;
}
}
}
activity_main.xml:
2.綁定服務(wù)并傳遞數(shù)據(jù)(執(zhí)行服務(wù)的內(nèi)部代碼)
(1)在布局中添加三個按鈕,綁定服務(wù)、解除綁定服務(wù)、同步數(shù)據(jù),同步數(shù)據(jù)按鈕是用來同步activity傳到service的數(shù)據(jù)。
(2)給綁定服務(wù)和解除綁定服務(wù)按鈕添加監(jiān)聽器,執(zhí)行以下代碼
綁定服務(wù):bindService(new Intent(this,MyService.class),this, Context.BIND_AUTO_CREATE);
解除綁定服務(wù):unbindService(this);
(3)同時實(shí)現(xiàn)兩個方法onServiceConnected()和onServiceDisconnectid();
(4)在MyService類中添加一個Binder 類,該類內(nèi)添加一個成員方方法setData()用來實(shí)時更改數(shù)據(jù)。
public class Binder extendsandroid.os.Binder{public voidsetData(String data){
MyService.this.data =data;
}
}
(5)在MyService類中的onBind方法中添加return new Binder();返回上一步新建的類的一個對象作為一個activity與service綁定的紐帶。
(6)回到MainActivity.java,創(chuàng)建一個binder:MyService.Binder binder = null;
(7)在onServiceConnected()方法中添加?binder = (MyService.Binder) iBinder;
(8)在同步數(shù)據(jù)按鈕的onClick()方法中執(zhí)行以下代碼:
if(binder!=null){
binder.setData(etData.getText().toString());
}
至此完成綁定服務(wù)并傳遞數(shù)據(jù)。這樣的用法好處是不用每次同步數(shù)據(jù)時都發(fā)送一個intent,而是直接通過調(diào)用方法來同步數(shù)據(jù),保證了代碼的高效性,也很快捷。
3.綁定服務(wù)并傳遞數(shù)據(jù)(偵聽服務(wù)內(nèi)部狀態(tài))
利用java的回調(diào)機(jī)制,從activity傳遞數(shù)據(jù)到service,service接到數(shù)據(jù)或數(shù)據(jù)改變時回調(diào)回來呈現(xiàn)在activity中
(1)在MyService類中添加一個CallBack接口,添加抽象方法onDataChange()。
(2)在MyService類中創(chuàng)建CallBack的對象,并添加get和set方法。
(3)在binder類中添加一個getService()方法,返回MyService.this.
(4)回到外部的MainActivity,布局添加一個TextView用于顯示服務(wù)的狀態(tài)。
(5)在onServiceConnected方法中添加binder.getService().setCallback(),給service添加回調(diào)函數(shù),并且實(shí)現(xiàn)onDataChange方法,把數(shù)據(jù)通過Message傳給Handler。
(6)在MainActivity中添加一個Handler(由于安全機(jī)制,安卓的UI線程不允許隨意被調(diào)用。所以只能用Handler來改變UI),在Handler中改變TextView的值。
所有的代碼如下:
MyService.java:
importandroid.app.Service;importandroid.content.Intent;importandroid.os.Binder;importandroid.os.IBinder;public class MyService extendsService {private boolean running = false;private String data = "這是默認(rèn)信息";publicMyService() {
}
@OverridepublicIBinder onBind(Intent intent) {return newBinder();
}public class Binder extendsandroid.os.Binder{public voidsetData(String data){
MyService.this.data =data;
}publicMyService getService(){return MyService.this;
}
}
@Overridepublic int onStartCommand(Intent intent, int flags, intstartId) {
data= intent.getStringExtra("data");return super.onStartCommand(intent, flags, startId);
}
@Overridepublic voidonCreate() {super.onCreate();
running= true;newThread() {
@Overridepublic voidrun() {super.run();int i = 0;while(running){
i++;
String str= i+":"+data;
System.out.println(i+":"+data);if(callback!=null){
callback.onDataChange(str);
}try{
sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
@Overridepublic voidonDestroy() {super.onDestroy();
running= false;
}private CallBack callback = null;public voidsetCallback(CallBack callback) {this.callback =callback;
}publicCallBack getCallback() {returncallback;
}public static interfaceCallBack{voidonDataChange(String data);
}
}
activity_main.xml和MainActivity:
importandroid.content.ComponentName;importandroid.content.Context;importandroid.content.Intent;importandroid.content.ServiceConnection;importandroid.os.Handler;importandroid.os.IBinder;importandroid.os.Message;importandroid.support.v7.app.AppCompatActivity;importandroid.os.Bundle;importandroid.support.v7.widget.SwitchCompat;importandroid.view.View;importandroid.widget.EditText;importandroid.widget.TextView;importlayout.MyService;public class MainActivity extends AppCompatActivity implementsView.OnClickListener, ServiceConnection {privateEditText etData;privateTextView tvOut;private MyService.Binder binder = null;
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etData=(EditText) findViewById(R.id.etData);
findViewById(R.id.btnStartSevice).setOnClickListener(this);
findViewById(R.id.btnStopSevice).setOnClickListener(this);
findViewById(R.id.btnBindService).setOnClickListener(this);
findViewById(R.id.btnUnbindService).setOnClickListener(this);
findViewById(R.id.btnSyncData).setOnClickListener(this);
tvOut=(TextView) findViewById(R.id.tvOut);
}
@Overridepublic voidonClick(View view) {switch(view.getId()) {caseR.id.btnStartSevice:
Intent i= new Intent(this, MyService.class);
i.putExtra("data",etData.getText().toString());
startService(i);break;caseR.id.btnStopSevice:
stopService(new Intent(this,MyService.class));break;caseR.id.btnBindService:
bindService(new Intent(this,MyService.class),this, Context.BIND_AUTO_CREATE);break;caseR.id.btnUnbindService:
unbindService(this);break;caseR.id.btnSyncData:if(binder!=null){
binder.setData(etData.getText().toString());
}break;
}
}
@Overridepublic voidonServiceConnected(ComponentName componentName, IBinder iBinder) {
binder=(MyService.Binder) iBinder;
binder.getService().setCallback(newMyService.CallBack() {
@Overridepublic voidonDataChange(String data) {
Message msg= newMessage();
Bundle b= newBundle();
b.putString("data",data);
msg.setData(b);
handler.sendMessage(msg);
}
});
}
@Overridepublic voidonServiceDisconnected(ComponentName componentName) {
}private Handler handler = newHandler(){
@Overridepublic voidhandleMessage(Message msg) {super.handleMessage(msg);
tvOut.setText(msg.getData().getString("data"));
}
};
}
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的安卓用于组件传递参数的对象是_入门篇:7.组件2:Android Service-service的数据传递与通信...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fpxpress.exe是什么进程 有什
- 下一篇: android 动态换肤框架,GitHu