美文网首页
Android基础知识—Service通信

Android基础知识—Service通信

作者: wshlin | 来源:发表于2016-04-05 19:46 被阅读108次

    1. 启动Service并传递数据

    新建项目ConnectService,在 activity_main.xml 修改布局为线性,走向垂直,添加两个Button和一个EditText。

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="默认信息" 
        android:id="@+id/etData"/>
    <Button
        android:text="启动服务"
        android:id="@+id/btnStartService" />
    <Button
        android:text="停止服务"
        android:id="@+id/btnStopService" />
    

    然后创建一个Service,接着在 MainActivity.java 创建事件监听器:

    private EditText etData;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        etData = (EditText) findViewById(R.id.etData);
        findViewById(R.id.btnStartService).setOnClickListener(this);
        findViewById(R.id.btnStopService).setOnClickListener(this);
    }
    
    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.btnStartService:
                Intent i = new Intent(this, MyService.class);
                i.putExtra("data", etData.getText().toString()); //启动时,传递信息过去。
                startService(i);
                break;
            case R.id.btnStopService:
                stopService(new Intent(this, MyService.class));
                break;
        }
    }
    

    之后在 MyService.java 里边重写 onCreate() 和 onDestroy():

    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;
        }
    }
    

    运行点击启动,控制台输出:默认信息。
    修改文本为 啦啦啦,点击启动,控制台输出:啦啦啦。
    通过这种方式就可以在外界与一个服务进行通信。

    2. 绑定Service进行通信(上)

    通过Binder的方式在Activity和Servise组件中进行通信。相比startService那种方式更加方便,而且也会更加高效,因为这是直接的方法调用,比发一个Intent要方便得多和快得多。

    在 activity_main.xml 新添三个按钮:

    <Button
        android:text="绑定服务"
        android:id="@+id/btnBindService" />
    <Button
        android:text="解除绑定服务"
        android:id="@+id/btnUnBindService" />
    <Button
        android:text="同步数据"
        android:id="@+id/btnSyncData" />
    

    在 MaiinActivity.java 添加

    private MyService.Binder binder = null;
    findViewById(R.id.btnBindService).setOnClickListener(this);
    findViewById(R.id.btnUnBindService).setOnClickListener(this);
    findViewById(R.id.btnSyncData).setOnClickListener(this);
    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 name, IBinder service) {
        binder = (MyService.Binder) service; //这里访问到的就是MyService.java里边onBind方法的返回值。
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {
    
    }
    

    在 MyService.java 里创建一个 Binder 类用于连接 Activity 和 Service 组件:

    @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;
        }
    }
    

    3. 绑定Service进行通信(下)

    将内部的信息呈现到外界,

    修改 MyService.java:

    @Override
    public void onCreate() {
        super.onCreate();
        running = true;
        new Thread(){  // 线程来输出语句
            @Override
            public void run() {
                super.run();
                int i = 0;
                while(running){
                    i++;
                    System.out.println(i+":"+data); //这段只会在控制台输出,现在是想把它呈现到activity去
                    try { // 每隔一秒
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }   
    

    在主布局activity_main.xml添加一个 TextView:

    <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tvOut"/>
    

    然后在 MianActivity.java 里边获取到它的Id:

    private TextView tvOut;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvOut = (TextView) findViewById(R.id.tvOut);
    }
    

    接下就是如何让内部通知外界,使用回调机制,如何做呢,修改 MyService.java:

    private Callback callback = null;
    public static interface Calback{ //写一个接口
        void onDataChange(String data); //发一个文字出去
    }
    public void setCallback(Callback callback) {
        this.callback = callback;
    }
    public Callback getCalkback(){
        return callback;
    }
    
    @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;   // newadd
                    System.out.println(str);   // newadd
    
                    if(callback!=null) {       //向外界派发 newadd
                        callback.onDataChange(str);
                    }
    
                    try { // 每隔一秒
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
    

    那么外界如何来添加这个事件的绑定呢?我们可以在Binder类里面写一公开的函数

    public class Binder extends  android.os.Binder{
        public MyService getService(){
            return MyService.this;
        }
    }
    

    接下来我们在外界就可以访问到它了,修改 MainActivity.java :

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        binder = (MyService.Binder) service;
        binder.getService().setCallback(new MyService.Callback() {
            @Override
            public void onDataChange(String data) { //在这里我们就可以获取Service内部所改变的数据了
                // 接着将数据传给tvOut输出到activity
                // 由于不能直接使用tvOut.setText(),我们定义一个handler
                Message msg = new Message();
                Bundle b = new Bundle();
                b.putString("data", data);
                msg.setData(b);  // 附加上一个数据
                handler.sendMessage(msg);  //把msg传过去
            }
        });
    }
    
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // 这里获取到msg,进一步处理就能把数据呈现到activity去了。
            tvOut.setText(msg.getData().getString("data"));
        }
    };
    

    运行启动就可以看到Service内部字符串输出到activity了。

    相关文章

      网友评论

          本文标题:Android基础知识—Service通信

          本文链接:https://www.haomeiwen.com/subject/ddbplttx.html