cvmachine.com - 申博开户网

查找: 您的方位主页 > 手机频道 > 阅览资讯:Android Service与Activity之间通讯的几种办法

Android Service与Activity之间通讯的几种办法

2019-03-30 19:22:20 来历:www.cvmachine.com 【

转载请注明地址http://blog.csdn.net/xiaanming/article/details/9750689

在Android中,Activity首要担任前台页面的展现,Service首要担任需求长时间运转的使命,所以在咱们实践开发中,就会常常遇到Activity与Service之间的通讯,咱们一般在Activity中发动后台Service,经过Intent来发动,Intent中咱们能够传递数据给Service,而当咱们Service履行某些操作之后想要更新UI线程,咱们应该怎么做呢?接下来我就介绍两种办法来完成Service与Activity之间的通讯问题

  • 经过Binder目标

当Activity经过调用bindService(Intent service, ServiceConnection conn,int flags),咱们能够得到一个Service的一个目标实例,然后咱们就能够拜访Service中的办法,咱们仍是经过一个比方来了解一下吧,一个模仿下载的小比方,带咱们了解一下经过Binder通讯的办法

首要咱们新建一个工程Communication,然后新建一个Service类

 

package com.example.communication;

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

public class MsgService extends Service {
/**
 * 进展条的最大值
 */
public static final int MAX_PROGRESS = 100;
/**
 * 进展条的进展值
 */
private int progress = 0;

/**
 * 添加get()办法,供Activity调用
 * @return 下载进展
 */
public int getProgress() {
return progress;
}

/**
 * 模仿下载使命,每秒钟更新一次
 */
public void startDownLoad(){
new Thread(new Runnable() {

@Override
public void run() {
while(progress < MAX_PROGRESS){
progress += 5;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}).start();
}


/**
 * 回来一个Binder目标
 */
@Override
public IBinder onBind(Intent intent) {
return new MsgBinder();
}

public class MsgBinder extends Binder{
/**
 * 获取当时Service的实例
 * @return
 */
public MsgService getService(){
return MsgService.this;
}
}

}
上面的代码比较简单,注释也比较具体,最基本的Service的使用了,相信你看得懂的,咱们调用startDownLoad()办法来模仿下载使命,然后每秒更新一次进展,但这是在后台进行中,咱们是看不到的,所以有时分咱们需求他能在前台显现下载的进展问题,所以咱们接下来就用到Activity了
Intent intent = new Intent("com.example.communication.MSG_ACTION"); 
bindService(intent, conn, Context.BIND_AUTO_CREATE);
经过上面的代码咱们就在Activity绑定了一个Service,上面需求一个ServiceConnection目标,它是一个接口,咱们这儿运用了匿名内部类

 

ServiceConnection conn = new ServiceConnection() {

@Override
public void onServiceDisconnected(ComponentName name) {

}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//回来一个MsgService目标
msgService = ((MsgService.MsgBinder)service).getService();

}
};

在onServiceConnected(ComponentName name, IBinder service) 回调办法中,回来了一个MsgService中的Binder目标,咱们能够经过getService()办法来得到一个MsgService目标,然后能够调用MsgService中的一些办法,Activity的代码如下

 

package com.example.communication;

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.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class MainActivity extends Activity {
private MsgService msgService;
private int progress = 0;
private ProgressBar mProgressBar;


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


//绑定Service
Intent intent = new Intent("com.example.communication.MSG_ACTION");
bindService(intent, conn, Context.BIND_AUTO_CREATE);


mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);
Button mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//开端下载
msgService.startDownLoad();
//监听进展
listenProgress();
}
});

}


/**
 * 监听进展,每秒钟获取调用MsgService的getProgress()办法来获取进展,更新UI
 */
public void listenProgress(){
new Thread(new Runnable() {

@Override
public void run() {
while(progress < MsgService.MAX_PROGRESS){
progress = msgService.getProgress();
mProgressBar.setProgress(progress);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}).start();
}

ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {

}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//回来一个MsgService目标
msgService = ((MsgService.MsgBinder)service).getService();

}
};

@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}


}
其实上面的代码我仍是有点疑问,便是监听进展改动的那个办法我是直接在线程中更新UI的,不是说不能在其他线程更新UI操作吗,可能是ProgressBar比较特别吧,我也没去研讨它的源码,知道的朋友能够告诉我一声,谢谢!

上面的代码就完成了在Service更新UI的操作,但是你发现了没有,咱们每次都要主动调用getProgress()来获取进展值,然后隔一秒在调用一次getProgress()办法,你会不会觉得很被迫呢?可不能够有一种办法当Service中进展发生改动主动告诉Activity,答案是必定的,咱们能够利用回调接口完成Service的主动告诉,不了解回调办法的能够看看http://blog.csdn.net/xiaanming/article/details/8703708

新建一个回调接口

 

public interface OnProgressListener {
void onProgress(int progress);
}
MsgService的代码有一些小小的改动,为了便利咱们看懂,我仍是将一切代码贴出来
package com.example.communication;

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

public class MsgService extends Service {
/**
 * 进展条的最大值
 */
public static final int MAX_PROGRESS = 100;
/**
 * 进展条的进展值
 */
private int progress = 0;

/**
 * 更新进展的回调接口
 */
private OnProgressListener onProgressListener;


/**
 * 注册回调接口的办法,供外部调用
 * @param onProgressListener
 */
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
}

/**
 * 添加get()办法,供Activity调用
 * @return 下载进展
 */
public int getProgress() {
return progress;
}

/**
 * 模仿下载使命,每秒钟更新一次
 */
public void startDownLoad(){
new Thread(new Runnable() {

@Override
public void run() {
while(progress < MAX_PROGRESS){
progress += 5;

//进展发生改动告诉调用方
if(onProgressListener != null){
onProgressListener.onProgress(progress);
}

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

}
}
}).start();
}


/**
 * 回来一个Binder目标
 */
@Override
public IBinder onBind(Intent intent) {
return new MsgBinder();
}

public class MsgBinder extends Binder{
/**
 * 获取当时Service的实例
 * @return
 */
public MsgService getService(){
return MsgService.this;
}
}

}
Activity中的代码如下
package com.example.communication;

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.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class MainActivity extends Activity {
private MsgService msgService;
private ProgressBar mProgressBar;


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


//绑定Service
Intent intent = new Intent("com.example.communication.MSG_ACTION");
bindService(intent, conn, Context.BIND_AUTO_CREATE);


mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);
Button mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//开端下载
msgService.startDownLoad();
}
});

}


ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {

}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//回来一个MsgService目标
msgService = ((MsgService.MsgBinder)service).getService();

//注册回调接口来接收下载进展的改动
msgService.setOnProgressListener(new OnProgressListener() {

@Override
public void onProgress(int progress) {
mProgressBar.setProgress(progress);

}
});

}
};

@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}


}
用回调接口是不是愈加的便利呢,当进展发生改动的时分Service主动告诉Activity,Activity就能够更新UI操作了

当咱们的进展发生改动的时分咱们发送一条播送,然后在Activity的注册播送接收器,接收到播送之后更新ProgressBar,代码如下

package com.example.communication;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class MainActivity extends Activity {
private ProgressBar mProgressBar;
private Intent mIntent;
private MsgReceiver msgReceiver;


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

//动态注册播送接收器
msgReceiver = new MsgReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.communication.RECEIVER");
registerReceiver(msgReceiver, intentFilter);


mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);
Button mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//发动服务
mIntent = new Intent("com.example.communication.MSG_ACTION");
startService(mIntent);
}
});

}


@Override
protected void onDestroy() {
//中止服务
stopService(mIntent);
//刊出播送
unregisterReceiver(msgReceiver);
super.onDestroy();
}


/**
 * 播送接收器
 * @author len
 *
 */
public class MsgReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
//拿到进展,更新UI
int progress = intent.getIntExtra("progress", 0);
mProgressBar.setProgress(progress);
}

}

}

package com.example.communication;

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

public class MsgService extends Service {
/**
 * 进展条的最大值
 */
public static final int MAX_PROGRESS = 100;
/**
 * 进展条的进展值
 */
private int progress = 0;

private Intent intent = new Intent("com.example.communication.RECEIVER");


/**
 * 模仿下载使命,每秒钟更新一次
 */
public void startDownLoad(){
new Thread(new Runnable() {

@Override
public void run() {
while(progress < MAX_PROGRESS){
progress += 5;

//发送Action为com.example.communication.RECEIVER的播送
intent.putExtra("progress", progress);
sendBroadcast(intent);

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

}
}
}).start();
}



@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startDownLoad();
return super.onStartCommand(intent, flags, startId);
}



@Override
public IBinder onBind(Intent intent) {
return null;
}


}
总结:
  1. Activity调用bindService (Intent service, ServiceConnection conn, int flags)办法,得到Service目标的一个引证,这样Activity能够直接调用到Service中的办法,假如要主动告诉Activity,咱们能够利用回调办法
  2. Service向Activity发送音讯,能够运用播送,当然Activity要注册相应的接收器。比方Service要向多个Activity发送相同的音讯的话,用这种办法就更好


 

 


 

 
 

本文地址:http://www.cvmachine.com/a/luyou/100047.html
Tags: Android service Activity
修改:申博开户网
关于咱们 | 联络咱们 | 友情链接 | 网站地图 | Sitemap | App | 回来顶部