zoukankan      html  css  js  c++  java
  • (六)Android中Service通信

    一、启动Service并传递参数

    传递参数时只需在startService启动的Intent中传入数据便可,接收参数时可在onStartCommand函数中通过读取第一个参数Intent的内容来实现

    1.MainActivity.java

    package com.example.shiyanshi.serviceconnected;

    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.EditText;


    public class MainActivity extends Activity implements View.OnClickListener {
    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    editText= (EditText) findViewById(R.id.editText);
    findViewById(R.id.btnStartService).setOnClickListener(this);
    findViewById(R.id.btnStopService).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
    switch (view.getId()){
    case R.id.btnStartService:

    Intent intent=new Intent(MainActivity.this,MyService.class);
    intent.putExtra("data",editText.getText().toString());
    startService(intent);

                    break;
    case R.id.btnStopService:
    stopService(new Intent(MainActivity.this,MyService.class));
    }

    }
    }

    2.MyService.java

    package com.example.shiyanshi.serviceconnected;

    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;

    public class MyService extends Service {
    private String data;
    private boolean flag;

    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();
    flag=true;
    new Thread() {
    @Override
    public void run() {
    super.run();
    while (flag) {
    System.out.println(data);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }.start();
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    flag=false;
    }
    }

     

    3.布局文件

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <EditText android:text="@string/hello_world" android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/editText"/>

    <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="启动服务"
    android:id="@+id/btnStartService" />

    <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="停止服务"
    android:id="@+id/btnStopService" />

    </LinearLayout>
    
    

    二、绑定Service进行通信

    (1)Activity向Service传递消息

    绑定服务后,Activity和Service之间可以通过android.os.Binder进行通信,当绑定服务时首先调用onCreate函数,然后调用Service类的onBind函数返回一个Binder,之后会调用Activity类中实现的onServiceConnected函数,该函数的第二个参数IBinder iBinder是Service类中onBind方法的返回值,通过这个Binder二者便可以成功通信。

     

     

    1.MainActivity.java

    package com.example.shiyanshi.serviceconnected;

    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.EditText;


    public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {
    private EditText editText;
    private MyService.Binder binder=null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    editText= (EditText) findViewById(R.id.editText);
    findViewById(R.id.btnStartService).setOnClickListener(this);
    findViewById(R.id.btnStopService).setOnClickListener(this);

    findViewById(R.id.btnBindService).setOnClickListener(this);
    findViewById(R.id.btnUnbindService).setOnClickListener(this);
    findViewById(R.id.btnSyncData).setOnClickListener(this);

        }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
    return true;
    }

    return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View view) {
    switch (view.getId()){
    case R.id.btnStartService:
    Intent intent=new Intent(MainActivity.this,MyService.class);
    intent.putExtra("data",editText.getText().toString());
    startService(intent);
    break;
    case R.id.btnStopService:
    stopService(new Intent(MainActivity.this, MyService.class));
    break;

    case R.id.btnBindService:
    bindService(new Intent(MainActivity.this, MyService.class), this, Context.BIND_AUTO_CREATE);
    break;
    case R.id.btnUnbindService:
    unbindService(this);
    break;
    case R.id.btnSyncData:
    if(binder!=null){
    System.out.println("bind in not null");
    binder.setData(editText.getText().toString()); //调用Bind中实现的数据交互方法
    }
    break;

            }

    }

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    System.out.println("*****Connected Successful*******");

    binder= (MyService.Binder) iBinder;

        }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
    System.out.println("*****Disconnected Successful*******");

    }
    }

    2.MyService.java

    package com.example.shiyanshi.serviceconnected;

    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;

    public class MyService extends Service {
    private String data="default info";
    private boolean flag;

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    // throw new UnsupportedOperationException("Not yet implemented");

    return new Binder(); //返回值会传给onServiceConnected函数的第二个参数IBinder

        }   
        //该类是Activity和Service进行交互数据的接口

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


    }

    @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();
    System.out.println("*******onCreate********");
    flag=true;
    new Thread() {
    @Override
    public void run() {
    super.run();
    while (flag) {
    System.out.println(data);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }.start();
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    System.out.println("******onDestroy******");
    flag=false;
    }
    }

    (2)Service向Activity传递消息,并将传递的数据显示到Activity中

    主要通过在Service中设定一个回调函数的接口,并定义一个该接口的引用,该引用的实例化是在Activity中进行的,实例化的同时会重写该接口中定义的回调函数,让该回调函数发送一个消息,并且在消息处理器(Handler)中进行更新UI线程的内容;此外在新开的Thread线程中调用该回调函数进行更新数据。

    1.MainActivity.java

    package com.example.shiyanshi.serviceconnected;

    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.Message;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;

    import org.w3c.dom.Text;

    import java.util.logging.Handler;


    public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {
    private EditText editText;
    private MyService.Binder binder=null;
    private TextView tvOut;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    editText= (EditText) findViewById(R.id.editText);
    tvOut=(TextView)findViewById(R.id.tvOut);

    findViewById(R.id.btnStartService).setOnClickListener(this);
    findViewById(R.id.btnStopService).setOnClickListener(this);
    findViewById(R.id.btnBindService).setOnClickListener(this);
    findViewById(R.id.btnUnbindService).setOnClickListener(this);
    findViewById(R.id.btnSyncData).setOnClickListener(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
    return true;
    }

    return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View view) {
    switch (view.getId()){
    case R.id.btnStartService:
    Intent intent=new Intent(MainActivity.this,MyService.class);
    intent.putExtra("data",editText.getText().toString());
    startService(intent);
    break;
    case R.id.btnStopService:
    stopService(new Intent(MainActivity.this, MyService.class));
    break;
    case R.id.btnBindService:
    bindService(new Intent(MainActivity.this, MyService.class), this, Context.BIND_AUTO_CREATE);
    break;
    case R.id.btnUnbindService:
    unbindService(this);
    break;
    case R.id.btnSyncData:
    if(binder!=null){
    System.out.println("bind in not null");
    binder.setData(editText.getText().toString());
    }
    break;
    }

    }

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    System.out.println("*****Connected Successful*******");
    binder= (MyService.Binder) iBinder;

    //设置回调函数,在回调函数中通过发送消息和消息处理器进行修改UI线程要显示的内容
    binder.getService().setCallback(new MyService.Callback() {
    @Override
    public void onDataChange(String data) {
    //tvOut.setText(data); 这里不可以直接设置,因为由新创建的线程去调用这个函数,不允许直接修改UI线程的内容
    Message msg=new Message();
    Bundle bundle=new Bundle();
    bundle.putString("data",data);
    msg.setData(bundle);
    handler.sendMessage(msg); //通过handler发送消息
    }
    });

        }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
    System.out.println("*****Disconnected Successful*******");

    }
     

    //消息处理函数,接收Message并进行处理


    private android.os.Handler handler=new android.os.Handler(){
    @Override
    public void handleMessage(Message msg) {
    super.handleMessage(msg);
    tvOut.setText(msg.getData().getString("data"));

    }
    };

    }
     

    2.MyService.java

    package com.example.shiyanshi.serviceconnected;

    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;

    public class MyService extends Service {
    private String data="default info";
    private boolean flag;

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    // throw new UnsupportedOperationException("Not yet implemented");
    System.out.println("******onBind*****");
    return new Binder(); //返回值会传给onServiceConnected函数的第二个参数IBinder
    }
    //该类是Activity和Service进行交互数据的接口
    public class Binder extends android.os.Binder{
    public void setData(String data) {
    MyService.this.data=data;
    }

    //获取当前的MyService类的引用
    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();
    System.out.println("*******onCreate********");
    flag=true;

    new Thread() {
    @Override
    public void run() {
    super.run();
    int i=0;
    while (flag) {
    i++;
    String str=i+":"+data;
    System.out.println(str);

    //由新创建的线程去调用这个函数,不允许直接修改UI线程的内容
    if (callback!=null){
    callback.onDataChange(str);
    }

                        try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }.start();
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    System.out.println("******onDestroy******");
    flag=false;
    }

    //创建的接口用于回调,回调函数(onDataChange)具体是在Activity中实现的



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









    }

     

     
  • 相关阅读:
    IT发烧友,一个真正的技术交流群
    IT发烧友,一个真正的技术交流群
    IT发烧友,一个真正的技术交流群
    IT发烧友,一个真正的技术交流群
    视频加密技术演进
    数字的二进制表示方法(反码、补码)
    Spring 当 @PathVariable 遇上 【. # /】等特殊字符
    spring boot系列03--spring security (基于数据库)登录和权限控制(下)
    嵌入式Tomcat容器的参数(maxParameterCount)设定
    spring boot系列02--Thymeleaf+Bootstrap构建页面
  • 原文地址:https://www.cnblogs.com/ql698214/p/5111422.html
Copyright © 2011-2022 走看看