安卓IntentService借助BoradcastReceiver与Activity通信

我们都知道安卓UI线程(Activity)里面禁止进行耗时操作,否则将会抛出异常。因此我们如需执行长时间耗时任务(比如上传、下载等任务)的话,还需的单独开一个任务线程来执行,这里我们可以选择IntentService或Service来在后台执行我们的耗时任务。如果任务处理结果要显示到UI界面上的话,那么选择IntentService比较合适。如果不需要在UI上显示,那么二者皆可。下面我主要讲解如何使用IntentService,以及我使用过程中出现的一些错误。

 

首先定义TimeService类,继承于IntentService:

package com.vector.com.card.service;

import android.app.IntentService;
import android.content.Intent;

import com.vector.com.card.view.HomeActivity;

public class TimeService extends IntentService {

public TimeService() {
super("TimeService");
}

@Override
protected void onHandleIntent(Intent intent) {
        //每分钟发送一次广播,提醒更新UI界面内容
        //定义intent,action的值为“action.timeUpdate”
Intent timeUpdate = new Intent(HomeActivity.action);
while (true) {
//发送广播
getApplicationContext().sendBroadcast(timeUpdate);
try {
                //线程休眠1分钟之后继续执行
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

 

然后在HomeActivity中定义内部类MyBroadcastReceiver,继承自BroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
        //没接收到一次广播就执行一次initNotice()方法
initNotice();
}
}

 

上面出现的initNotice方法里面就是和更行UI界面有关的代码啦

public void initNotice() {
List<Notice> list = new NoticeDao(this).queryAllByUserId(userid);
Notice notice;
if (list.size() == 1) {
notice = list.get(0);
if (notice.getStatus().equals("0")) {
iv_notice_icon_1.setVisibility(View.VISIBLE);
} else {
iv_notice_icon_1.setVisibility(View.GONE);
}
tv_notice_content_1.setText(notice.getContent());
tv_notice_time_1.setText(Utils.getFormatedTime(notice.getTime()));
} else if (list.size() >= 2) {
notice = list.get(0);
if (notice.getStatus().equals("0")) {
iv_notice_icon_1.setVisibility(View.VISIBLE);
} else {
iv_notice_icon_1.setVisibility(View.GONE);
}
tv_notice_content_1.setText(notice.getContent());
tv_notice_time_1.setText(Utils.getFormatedTime(notice.getTime()));

notice = list.get(1);
if (notice.getStatus().equals("0")) {
iv_notice_icon_2.setVisibility(View.VISIBLE);
} else {
iv_notice_icon_2.setVisibility(View.GONE);
}
tv_notice_content_2.setText(notice.getContent());
tv_notice_time_2.setText(Utils.getFormatedTime(notice.getTime()));
} else {
iv_notice_icon_1.setVisibility(View.GONE);
iv_notice_icon_2.setVisibility(View.GONE);
tv_notice_content_1.setText("无消息");
tv_notice_content_2.setText("无消息");
}
}

 

下一步就是注册广播了。我们都知道广播的注册有两种形式:1.静态注册。在AndroidManifest.xml中使用标签注册;2.动态注册。就是在代码中动态注册,哪里要使用就在哪注册/取消;这2种注册方式除了作用域外,没有什么太大的不同。下面是动态注册的代码:

public void registBroadcast() {
    //实例化广播对象
broadcastReceiver = new MyBroadcastReceiver();
    //实例化广播过滤器,只拦截指定的广播
filter = new IntentFilter(action);
    //注册广播
    this.registerReceiver(broadcastReceiver, filter);
}  

 

再接着就是启动IntentService了

//实例化Service。启动service与启动Activity方式大同小异
Intent intentService = new Intent(this, TimeService.class);
//启动
startService(intentService);

 

至此,关于IntentService和BroadcastReceiver的讲解就结束啦…但是呢,本文的内容并未结束。有兴趣的请继续往下看,多谢支持^_^。

 

下面再来讲一讲我在实现这一操作过程中遇到的一个问题,虽然问题低级,但也值得留意。

问题描述:在TimeSerivce类的onHandleIntent方法中有个参数intent被误用来发送广播,导致接收不到此广播。

@Override
protected void onHandleIntent(Intent intent) {
       
//Intent timeUpdate = new Intent(HomeActivity.action);正确用法

while (true) {
//发送广播
getApplicationContext().sendBroadcast(timeUpdate);//正确用法getApplicationContext().sendBroadcast(intent);//错误用法

try {
                //线程休眠1分钟之后继续执行
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

问题分析:onHandleIntent方法自带的intent参数在IntentService被创建时赋值,它的值便是我们启动service是传递过来的intentService:

Intent intentService = new Intent(this, TimeService.class);

因此它不能再用来启动广播,从而导致广播发送失败。

 

至此,本文就就顺利结束啦^_^!!鉴于本人是热衷于安卓开发的安卓菜鸟,如有疏漏和改进的地方烦请各位大神指教,不胜感激。

1、最后打个广告:高效、实用的日程管理APP,下载链接:https://pan.baidu.com/s/1pKCUGWF

2、以及本博客的所有源代码github地址:https://github.com/Code-Yeong/Card

posted @ 2017-09-26 13:06  CoderYeong  阅读(1292)  评论(0编辑  收藏  举报