入门篇:7.组件2:Android Service-service的数据传递与通信

您所在的位置:网站首页 同步安卓数据 入门篇:7.组件2:Android Service-service的数据传递与通信

入门篇:7.组件2:Android Service-service的数据传递与通信

2024-07-11 03:24| 来源: 网络整理| 查看: 265

(由于对java的回调机制和线程理解的不够透彻,所以这块内容我理解了好久,尤其是绑定服务传递数据,一句一句写一句一句看,对我来说挺难理解的。以后还要多看几遍--!)

      既然单纯的启动或跳转activity没有意义,那么同样的,单纯的启动或绑定service也是无意义的,实际应用中常常要携带数据启动service或绑定service。

1.启动service并传递数据

(1)新建一个Service:MyService

(2)在布局中添加两个按钮,启动服务和停止服务,和一个EditText,用户传递数据

(3)给两个按钮添加监听器,分别执行startService方法和stopService方法

(4)在MyService类中onCreate方法添加一个控制台输出语句,便于我们看到服务的状态和数据的传递效果。

(5)在开始按钮的onClick方法中添加intent.putExtra("data",etData.getText().toString()),用于在activity中初始化和传递数据。

(6)在MyService类中重写onStartCommand方法,其中的intent参数用于接收activity传来的数据。intent.getStringExtra("data");

此时运行程序,点击启动服务,会在控制台输出界面输入框中的数据,更改数据再次点击启动服务,控制台输出的数据也随之改变。点击停止服务,控制台停止输出。

代码如下:

MyService.java:

public class MyService extends Service { private boolean running = false; private String data = "这是默认信息"; public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { data = intent.getStringExtra("data"); return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); running = true; new Thread() { @Override public void run() { super.run(); while(running){ System.out.println(data); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } @Override public void onDestroy() { super.onDestroy(); running = false; } }

MainActivity.java:

import android.os.Bundle; import android.support.v7.widget.SwitchCompat; import android.view.View; import android.widget.EditText; import layout.MyService; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private EditText etData; @Override protected void onCreate(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); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btnStartSevice: Intent i = new Intent(this, MyService.class); i.putExtra("data",etData.getText().toString()); startService(i); break; case R.id.btnStopSevice: stopService(new Intent(this,MyService.class)); break; } } }

activity_main.xml:

2.绑定服务并传递数据(执行服务的内部代码)

 (1)在布局中添加三个按钮,绑定服务、解除绑定服务、同步数据,同步数据按钮是用来同步activity传到service的数据。

 (2)给绑定服务和解除绑定服务按钮添加监听器,执行以下代码

        绑定服务:bindService(new Intent(this,MyService.class),this, Context.BIND_AUTO_CREATE);

        解除绑定服务:unbindService(this);

 (3)同时实现两个方法onServiceConnected()和onServiceDisconnectid(); 

 (4)在MyService类中添加一个Binder 类,该类内添加一个成员方方法setData()用来实时更改数据。

public class Binder extends android.os.Binder{ public void setData(String data){ MyService.this.data = data; } }

 (5)在MyService类中的onBind方法中添加return new Binder();返回上一步新建的类的一个对象作为一个activity与service绑定的纽带。

 (6)回到MainActivity.java,创建一个binder:MyService.Binder binder = null;

 (7)在onServiceConnected()方法中添加 binder = (MyService.Binder) iBinder; 

 (8)在同步数据按钮的onClick()方法中执行以下代码:

if(binder!=null){ binder.setData(etData.getText().toString()); }

至此完成绑定服务并传递数据。这样的用法好处是不用每次同步数据时都发送一个intent,而是直接通过调用方法来同步数据,保证了代码的高效性,也很快捷。

3.绑定服务并传递数据(侦听服务内部状态)

利用java的回调机制,从activity传递数据到service,service接到数据或数据改变时回调回来呈现在activity中

(1)在MyService类中添加一个CallBack接口,添加抽象方法onDataChange()。

(2)在MyService类中创建CallBack的对象,并添加get和set方法。

(3)在binder类中添加一个getService()方法,返回MyService.this.

(4)回到外部的MainActivity,布局添加一个TextView用于显示服务的状态。

(5)在onServiceConnected方法中添加binder.getService().setCallback(),给service添加回调函数,并且实现onDataChange方法,把数据通过Message传给Handler。

(6)在MainActivity中添加一个Handler(由于安全机制,安卓的UI线程不允许随意被调用。所以只能用Handler来改变UI),在Handler中改变TextView的值。

所有的代码如下:

MyService.java:

import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; public class MyService extends Service { private boolean running = false; private String data = "这是默认信息"; public MyService() { } @Override public IBinder onBind(Intent intent) { return new Binder(); } public class Binder extends android.os.Binder{ public void setData(String data){ MyService.this.data = data; } public MyService getService(){ return MyService.this; } } @Override public int onStartCommand(Intent intent, int flags, int startId) { data = intent.getStringExtra("data"); return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); running = true; new Thread() { @Override public void run() { 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(); } @Override public void onDestroy() { super.onDestroy(); running = false; } private CallBack callback = null; public void setCallback(CallBack callback) { this.callback = callback; } public CallBack getCallback() { return callback; } public static interface CallBack{ void onDataChange(String data); } }

activity_main.xml和MainActivity:

import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.SwitchCompat; import android.view.View; import android.widget.EditText; import android.widget.TextView; import layout.MyService; public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection { private EditText etData; private TextView tvOut; private MyService.Binder binder = null; @Override protected void onCreate(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); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btnStartSevice: Intent i = new Intent(this, MyService.class); i.putExtra("data",etData.getText().toString()); startService(i); break; case R.id.btnStopSevice: stopService(new Intent(this,MyService.class)); break; case R.id.btnBindService: bindService(new Intent(this,MyService.class),this, Context.BIND_AUTO_CREATE); break; case R.id.btnUnbindService: unbindService(this); break; case R.id.btnSyncData: if(binder!=null){ binder.setData(etData.getText().toString()); } break; } } @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { binder = (MyService.Binder) iBinder; binder.getService().setCallback(new MyService.CallBack() { @Override public void onDataChange(String data) { Message msg = new Message(); Bundle b = new Bundle(); b.putString("data",data); msg.setData(b); handler.sendMessage(msg); } }); } @Override public void onServiceDisconnected(ComponentName componentName) { } private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); tvOut.setText(msg.getData().getString("data")); } }; }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3