Service为Android的四大组件之一,Android中service(服务)运行于后台,没有界面。和其他组件一样,service也运行在主线程中,因此不能用它来做耗时的请求或者动作。可以在服务中开启线程;
但是Service开启和停止都需要调用方法,如果没有及时关闭Service,服务会一直存活或者出现异常,对app内存造成了不必要的消耗;故在Android中引入了IntentService,可以进行耗时操作,且耗时操作结束后可以自动关闭Service。
在onHandleIntent方法中进行耗时操作,结束后会自行调用onDestory方法,不需要手动关闭Service。
Android中涉及到将服务器中数据变化信息通知给用户一般情况下有两种方法,推送和轮询,推送一般使用第三方,其大致原理是将客户端和服务器端建立一个长连接,比较耗电,但是即时性比较强,调用方便;轮询的原理是定时访问服务器,拿到返回数据,来确定当前数据是否发生变化,适合短时间数据请求,实时性差一点;但是更有针对性。
需求:在app启动后轮询状态,直到状态为真的时候,结束轮询,进行接下来的操作
思路:在app启动后,开始intentService,轮询,得到结果后将消息用广播的形式传给Activity,结束intentService
public class NewPollingService extends IntentService {
private boolean linkSign = false;
private String UUid = "";
private InternetConn internetConn;
private int status = 0;
private boolean sleepSign= true;
private int times = 0;
private boolean whileSign = false;
// private static final OkHttpClient client = new OkHttpClient.Builder().
// connectTimeout(30, TimeUnit.SECONDS).
// writeTimeout(30,TimeUnit.SECONDS).
// readTimeout(30,TimeUnit.SECONDS).
// build();
@SuppressLint("HandlerLeak")
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//发送广播
Intent intent=new Intent();
intent.putExtra("status", msg.what);
// intent.putExtra("content", msg.what+"conetnt");
intent.setAction("com.tarena.intentwechatdemo.InternetReceiver");
sendBroadcast(intent);
// Toast.makeText(NewPollingService.this, "IntetnService Running"+msg.what, Toast.LENGTH_SHORT)
// .show();
super.handleMessage(msg);
}
};
public NewPollingService() {
/**
* 这里只需要传入一个字符串就可以了
*/
super("MyIntentService");
}
/**
* 必须实现的抽象方法,我们的业务逻辑就是在这个方法里面去实现的 在这个方法里实现业务逻辑,我们就不用去关心ANR的问题
*/
@Override
protected void onHandleIntent(Intent intent) {
UUid = intent.getStringExtra("uuid");
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(InternetConn.BASE_URL)
.build();
internetConn = retrofit.create(InternetConn.class);
while(!linkSign){
if (sleepSign){
sleepSign = false;
Log.e("开始请求",""+System.currentTimeMillis());
Call<LoginStatus> statusCall = internetConn.postLoginStatus(UUid);
statusCall.enqueue(new Callback<LoginStatus>() {
@Override
public void onResponse(Call<LoginStatus> call, Response<LoginStatus> response) {
sleepSign = true;
status = response.body().getData().getStatus();
Log.e("==status==",""+status);
if (response.body().getData().getStatus()==200||response.body().getData().getStatus()==400){
linkSign = true;
}
if (response.body().getData().getStatus()==201){
handler.sendEmptyMessage(status);
}
}
@Override
public void onFailure(Call<LoginStatus> call, Throwable t) {
Log.e("失败",""+t);
sleepSign = true;
times++;
if (times==5){
linkSign = true;
}
}
});
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (times==5){
}else {
if (whileSign==false){
handler.sendEmptyMessage(status);
whileSign = true;
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
在Activity中注册广播
IntentFilter filter = new IntentFilter();
filter.addAction(IntentUtil.getActionSetTextName());
LocalBroadcastManager.getInstance(this).registerReceiver(mActionSetTextReceiver, filter);
在广播中处理数据
public class InternetReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("====","==onReceiver==");
Bundle bundle=intent.getExtras();
int status=bundle.getInt("status");
if (status==200){
// progersssDialog.setMsg("分析数据中...");
// progersssDialog.show();
showAnalysisSex();
}else if(status==400){
if (analysisDialog.isShowing()){
analysisDialog.dismiss();
}
initQRcode();
}else if (status==201){
if (!analysisDialog.isShowing()){
analysisDialog.show();
analysisDialog.setMsg("分析数据中...");
}
}
}
}
以上,便实现了简单的轮询功能