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("分析數據中...");
}
}
}
}
以上,便實現了簡單的輪詢功能