您的位置:首页 > 移动开发 > Android开发

Android学习之Activity与Service进行通信的三种方式

2016-09-18 18:50 399 查看

Activity与Service进行通信的三种方式

第一种 简单通信

直接通过Intent进行传值,我们在启动一个Service的时候通过Intent的对象向Service进行传值,这种方式传递值比较不方便,性能不是很高。

(1)在MainActivity中通过启动服务和终止服务的按钮分别调用startService(intent)和stopService(intent)来启动和停止服务

MainActivity

[java]
view plain
copy





public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {  
    private Intent intent;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        intent = new Intent(MainActivity.this, MyService.class);  
  
        findViewById(R.id.btyStartService).setOnClickListener(this);  
        findViewById(R.id.btyStopService).setOnClickListener(this);  
  
    }  
  
    @Override  
    public void onClick(View view) {  
        switch (view.getId()) {  
            case R.id.btyStartService://启动服务  
                intent.putExtra("data", editText.getText().toString());  
                startService(intent);  
                break;  
            case R.id.btyStopService://终止服务  
                stopService(intent);  
                break;  
             
        }  
    }  
   }  

(2)在Myservice中,我们通过onStartCommand(finalIntent
intent, int
flags, intstartId)这个函数来接收从Activity传过来的值
Myservice

[java]
view plain
copy





public class MyService extends Service {  
    private Boolean myflags = false;  
    private String data = "服务器正在执行";  
    private static final String TAG = "ActivityTest";  
    private Callback callback;  
    public MyService() {  
    }  
  
    @Override  
    public IBinder onBind(Intent intent) {  
              return new Binder();  
    }  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        myflags = true;  
        new Thread(){  
            @Override  
            public void run() {  
                super.run();  
                while(myflags){  
                    try {  
                        String str = data;  
                        Log.d(TAG, str);  
                        sleep(1000);  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                        Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();  
                    }  
                }  
                Log.d(TAG, "服务器已停止");  
            }  
  
        }.start();  
    }  
  
    @Override  
    public int onStartCommand(final Intent intent, int flags, int startId) {  
        data = intent.getStringExtra("data");  
        return super.onStartCommand(intent, flags, startId);  
    }  
}  

第二种

我们在绑定服务的时候,首先要做的就是让我们的MainActivity实现ServiceConnection类,实现这个类之后,我们还需要重写ServiceConnection类中的两个方法onServiceConnected和onServiceDisconnected,这两个方法分别是在绑定成功和服务所在进程崩溃的时候被调用,如果绑定成功了,那么onServiceConnected(ComponentName
componentName, IBinder iBinder) 就会被执行,然后第二个参数IBinder正是MyService中onBind()方法的返回值,因此我们可以通过这个返回值来想MyService传递数据。

[java]
view plain
copy





public IBinder onBind(Intent intent) {  
        Log.d(TAG, "服务器已绑定");  
       return new Binder();  
}  

(1)MyService 中我们创建一个Binder类,让其实现Android.os.Binder类,并且定义一个方法setData,然后我们通过onBind()方法将其对象返回MainActivity。

[java]
view plain
copy





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

MyService

[java]
view plain
copy





public class MyService extends Service {  
    private Boolean myflags = false;  
    private String data = "服务器正在执行";  
    private static final String TAG = "ActivityTest";  
    private Callback callback;  
    public MyService() {  
    }  
  
    @Override  
    public IBinder onBind(Intent intent) {  
        Log.d(TAG, "服务器已绑定");  
       return new Binder();  
    }  
  
    public class Binder extends android.os.Binder{  
        public void setData(String data){  
            MyService.this.data = data;  
        }  
    }  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        myflags = true;  
        new Thread(){  
            @Override  
            public void run() {  
                super.run();  
                while(myflags){  
                    //System.out.println("程序正在运行.....");  
                    try {  
                        String str = data;  
                        Log.d(TAG, str);  
                        sleep(1000);  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                        Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();  
                    }  
                }  
                Log.d(TAG, "服务器已停止");  
            }  
  
        }.start();  
    }  
  
    @Override  
    public int onStartCommand(final Intent intent, int flags, int startId) {  
        data = intent.getStringExtra("data");  
        return super.onStartCommand(intent, flags, startId);  
    }  
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        myflags = false;  
    }  
    @Override  
    public boolean onUnbind(Intent intent) {  
        return super.onUnbind(intent);  
    }  
  
}  

(2)在MainActivity中,首先添加一个Binder对象,然后在ServiceConnection中获取MyService中返回的Binder对象,接着我们通过Binder对象调用它的方法setData向其传递数据

MainActivity

[java]
view plain
copy





public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {  
  
    private Intent intent;  
    private EditText editText;  
    private TextView textView;  
    private MyService.Binder myBinder = null;//①  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        intent = new Intent(MainActivity.this, MyService.class);  
        editText = (EditText) findViewById(R.id.editText);  
        textView = (TextView) findViewById(R.id.textView);  
  
        findViewById(R.id.btyStartService).setOnClickListener(this);  
        findViewById(R.id.btyStopService).setOnClickListener(this);  
        findViewById(R.id.btyBindService).setOnClickListener(this);  
        findViewById(R.id.btyUnbindService).setOnClickListener(this);  
        findViewById(R.id.btySend).setOnClickListener(this);  
  
    }  
  
    @Override  
    public void onClick(View view) {  
        switch (view.getId()) {  
            case R.id.btyStartService://启动服务  
                intent.putExtra("data", editText.getText().toString());  
                startService(intent);  
                break;  
            case R.id.btyStopService://终止服务  
                stopService(intent);  
                break;  
            case R.id.btyBindService://绑定服务  
                bindService(intent, this, Context.BIND_AUTO_CREATE);  
                break;  
            case R.id.btyUnbindService://解除绑定  
                unbindService(this);  
                break;  
            case R.id.btySend://想MyService传递数据  
                if (myBinder != null) {  
                    myBinder.setData(editText.getText().toString());//③  
                }  
                break;  
        }  
    }  
    //一旦绑定成功就会执行该函数  
    @Override  
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {  
        myBinder = (MyService.Binder) iBinder;//②  
    }  
  
    @Override  
    public void onServiceDisconnected(ComponentName componentName) {  
  
    }  
  
}  

第三种,监听服务中的进程的变化
在MyService中
(1)添加一个公开的接口Callback

[java]
view plain
copy





public static interface Callback{  
        void onDataChange(String data);  
    }  

(2)在MyService内部添加一个变量

[java]
view plain
copy





private Callback callback;  
public void setCallback(Callback callback) {  
    this.callback = callback;  
}  
  
public Callback getCallback() {  
    return callback;  
}  

(3)向外界派发信息

[java]
view plain
copy





if (callback != null){  
    callback.onDataChange(str);  
}  

(4)在Binder中返回一个当前的MyService对象,然外部可以添加事件的绑定

[java]
view plain
copy





public MyService getMyService(){  
    return MyService.this;  
}  

MyService

[java]
view plain
copy





public class MyService extends Service {  
    private Boolean myflags = false;  
    private String data = "服务器正在执行";  
    private static final String TAG = "ActivityTest";  
    private Callback callback;  
    public MyService() {  
    }  
  
    @Override  
    public IBinder onBind(Intent intent) {  
        Log.d(TAG, "服务器已绑定");  
       return new Binder();  
    }  
  
    public class Binder extends android.os.Binder{  
        public void setData(String data){  
            MyService.this.data = data;  
        }  
        public MyService getMyService(){  
            return MyService.this;  
        }  
    }  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        myflags = true;  
        new Thread(){  
            @Override  
            public void run() {  
                super.run();  
                int i =1;  
                while(myflags){  
                    //System.out.println("程序正在运行.....");  
                    try {  
                        String str = i + ":" +data;  
                        Log.d(TAG, str);  
                        if (callback != null){  
                            callback.onDataChange(str);  
                        }  
                        sleep(1000);  
                        i++;  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                        Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();  
                    }  
                }  
                Log.d(TAG, "服务器已停止");  
            }  
  
        }.start();  
    }  
  
    @Override  
    public int onStartCommand(final Intent intent, int flags, int startId) {  
        data = intent.getStringExtra("data");  
        return super.onStartCommand(intent, flags, startId);  
    }  
  
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        myflags = false;  
    }  
  
    @Override  
    public boolean onUnbind(Intent intent) {  
        return super.onUnbind(intent);  
    }  
  
    public void setCallback(Callback callback) {  
        this.callback = callback;  
    }  
  
    public Callback getCallback() {  
        return callback;  
    }  
  
    public static interface Callback{  
        void onDataChange(String data);  
    }  
}  

在MainActivity中我们可以通过onServiceConnected方法中的iBinder对象来实现MyService中Callback的接口,在Android中有一个安全机制,辅助线程是不能直接修改主线程中的数据的,因此我们需要再定义一个Hander对象。

[java]
view plain
copy





//①  
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {  
    myBinder = (MyService.Binder) iBinder;  
    myBinder.getMyService().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);  
            hander.sendMessage(msg);  
        }  
    });  
}  
  
//②  
private Handler hander = new Handler(){  
    @Override  
    public void handleMessage(Message msg) {  
        super.handleMessage(msg);  
        textView.setText(msg.getData().getString("data"));  
    }  
};  

MainActivity

[java]
view plain
copy





public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {  
  
    private Intent intent;  
    private EditText editText;  
    private TextView textView;  
    private MyService.Binder myBinder = null;  
  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        intent = new Intent(MainActivity.this, MyService.class);  
        editText = (EditText) findViewById(R.id.editText);  
        textView = (TextView) findViewById(R.id.textView);  
  
        findViewById(R.id.btyStartService).setOnClickListener(this);  
        findViewById(R.id.btyStopService).setOnClickListener(this);  
        findViewById(R.id.btyBindService).setOnClickListener(this);  
        findViewById(R.id.btyUnbindService).setOnClickListener(this);  
        findViewById(R.id.btySend).setOnClickListener(this);  
  
    }  
  
    @Override  
    public void onClick(View view) {  
        switch (view.getId()) {  
            case R.id.btyStartService:  
                intent.putExtra("data", editText.getText().toString());  
                startService(intent);  
                break;  
            case R.id.btyStopService:  
                stopService(intent);  
                break;  
            case R.id.btyBindService:  
                bindService(intent, this, Context.BIND_AUTO_CREATE);  
                break;  
            case R.id.btyUnbindService:  
                unbindService(this);  
                break;  
            case R.id.btySend:  
                if (myBinder != null) {  
                    myBinder.setData(editText.getText().toString());  
                }  
                break;  
        }  
    }  
    //一旦绑定成功就会执行该函数  
    @Override  
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {  
        myBinder = (MyService.Binder) iBinder;  
        myBinder.getMyService().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);  
                hander.sendMessage(msg);  
            }  
        });  
    }  
  
    @Override  
    public void onServiceDisconnected(ComponentName componentName) {  
         
    }  
  
    private Handler hander = new Handler(){  
        @Override  
        public void handleMessage(Message msg) {  
            super.handleMessage(msg);  
            textView.setText(msg.getData().getString("data"));  
        }  
    };  
}  

在以上的代码中,按钮等控件可以自行添加
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: