Day15 Messenger & DownloadManager
- Messenger 信使
- DownloadManager 下载管理器
Messenger 信使
- 概述
- 使用方法
概述
Messenger引用了一个Handler对象,以便others能够向它发送消息(使用mMessenger.send(Message msg)方法)。
该类允许跨进程间基于Message的通信(即两个进程间可以通过Message进行通信),在服务端使用Handler创建一个Messenger,客户端持有这个Messenger就可以与服务端通信了。使用Messenger作为中介实现跨进程的线程间通信
使用步骤
- 服务端:mMessenger = new Messenger(mHandler)
- 客户端使用bindlerService请求连接远程
- 远程onBind方法返回一个bindler:return mMessenger.getBinder()
- 客户端使用远程返回的bindler得到一个信使(即得到远程信使)
- 客户端可以使用这个远程信使对象向远程发送消息:rMessenger.send(msg);
不能通过Message.obj参数,因此obj没有实现Parcelable接口
如果需要传送数据,可以通过==Message.setData(Bundle)
== 方法
示例代码
- 服务端
/**
* 基于Messenger信使实现两个进程之间的线程间通信: 应用间使用同一个Handler对象
* 1) 服务端:
*
* 1. 创建Service子类,在类中声明Handler和Messenger类对象
* 2. 在onBind()方法中,获取Messenger的IBinder对象,并返回
* 3. 注册Service,并声明隐式启动或绑定组件的Action
* @author apple
*
*/
public class PrintService extends Service {
//1. 声明和实例化Handler及Messenger类对象
private Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
//处理其它线间或进程发送过来的消息
Log.i("debug","--PrintService ---->handleMessage:"
+msg.getData().getString("info"));
Message replyMsg=Message.obtain();
replyMsg.what=2;
try {
msg.replyTo.send(replyMsg); //应答客户端: 向客户端回传消息
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
private Messenger messenger=new Messenger(mHandler);
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();//2.获取Messenger对象的IBinder接口对象
}
}
- 客户端
/**
* 基于Messenger实现应用间的线程间通信
* 1) 客户端
* 1. 声明Messenger对象
* 2. 声明并实例化ServiceConnection接口对象,在绑定服务组件时使用,用于监听绑定是否成功
* 3. 在合适的位置调用Context.bindService()方法进行绑定
* 4. 在ServiceConnection接口的onServiceConnected()方法中,
* 将方法的第二个参数作为实例化Messenger的构造方法参数使用。
* 5. 在合适的位置,调用Messenger对象的send(Message msg)向服务端的Handler中发送消息
*
* 2) 如果客户端需要接收服务端回传或应答的消息,需要实例化Handler和Messenger,
* 并将Messenger作为服务端应答的信使封装在向服务端发送的Message(消息)中
* @author apple
*
*/
public class MainActivity extends Activity {
//1. 声明Messenger对象
private Messenger messenger;
//2. 实例化ServiceConnection接口对象
private ServiceConnection conn=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO 绑定成功的回调方法
//4.实例化Messenger对象,并使用当前方法的第二个参数,传入到Messenger构造方法中
messenger=new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
private Handler replyHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
//接收服务端回传的消息
if(msg.what==2){
Toast.makeText(getApplicationContext(), "发送消息成功..", 1).show();
}
}
};
private Messenger replyMessenger=new Messenger(replyHandler); //应答信使
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//3.开始绑定服务组件
bindService(new Intent("com.qf.service07_messenger_server.PrintService"),
conn, BIND_AUTO_CREATE);
}
public void send(View v){
//5. 通过Messenger信使,向绑定服务组件所在的应用发送消息(由这一应用的Handler来处理的)
Message msg=Message.obtain();
//msg.obj="hello,Messenger~Server"; //此处会抛出异常,原因是String类没有实现Parcelable接口
Bundle data=new Bundle();
data.putString("info", "hello,Messenger~Server");
msg.setData(data);//设置发送消息的数据
//设置服务端应答信使
msg.replyTo=replyMessenger;
try {
messenger.send(msg); //通过信使开始向外部应用发送消息
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
DownloadManager 下载管理器
DownloadManager是系统开放给第三方应用使用的类,用于下载管理和查询,包含两个静态内部类DownloadManager.Query和DownloadManager.Request
- 核心方法
- 请求
- 查询
- 权限
核心方法
public long enqueue(Request request)
执行下载,并返回downloadIdpublic int remove(long… ids)
删除下载public Cursor query(Query query)
查询下载信息
COLUMN_ID
COLUMN_TITLE
COLUMN_URI
COLUMN_LOCAL_FILENAME
COLUMN_LOCAL_URI
COLUMN_LAST_MODIFIED_TIMESTAMP
COLUMN_DESCRIPTION
COLUMN_BYTES_DOWNLOADED_SO_FAR
COLUMN_TOTAL_SIZE_BYTES
public static Long getRecommendedMaxBytesOverMobile(Context context)
通过移动网络下载的最大字节数public String getMimeTypeForDownloadedFile(long id)
得到下载的mimeType
下载请求
使用的常量
- 请求网络类型
- NETWORK_MOBILE 2G/3G/4G 手机移动网络
- NETWORK_WIFI 无线Wifi网络
- 通知栏显示特性
- VISIBILITY_HIDDEN 隐藏通知栏
- VISIBILITY_VISIBLE 显示通知栏
- VISIBILITY_VISIBLE_NOTIFY_COMPLETED 开始和完成下载显示通知栏
- VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION 仅下载完成后显示通知栏
- 请求网络类型
DownloadManager.Request(Uri uri) 构造方法
setDestinationInExternalPublicDir(“dir”,”filename.jpg”) 设置下载文件存储的位置和文件名
setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, “a.3gp”); 设置文件存储到公共位置
request.allowScanningByMediaScanner();表示允许MediaScanner扫描到这个文件,默认不允许
request.setTitle(“下载提示”);设置下载中通知栏提示的标题
request.setDescription(“文件已下载完成”);设置下载中通知栏提示的介绍
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) 设置通知的显示特性
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
request.setMimeType(“application/com.trinea.download.file”);
request.addRequestHeader(String header, String value) 添加请求下载的网络链接的http头,比如User-Agent,gzip压缩等
下载状态查询
DownloadManager.Query() 构造方法
setFilterById(long …) 过滤下载文件的id
setFilterByStatus(int flags) 过滤下载状态
- DownloadManager.STATUS_FAILED 下载失败
- DownloadManager.STATUS_PAUSED 暂停下载
- DownloadManager.STATUS_PENDING 等待下载
- DownloadManager.STATUS_RUNNING 正在下载
- DownloadManager.STATUS_SUCCESSFUL 下载成功
setOnlyIncludeVisibleInDownloadsUi(boolean value) 过滤下载进度ui是否可见
权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />