您的位置:首页 > 理论基础 > 计算机网络

稳定的闹钟服务定时循环请求网络接口(可做类似即时通讯或者推送功能)

2017-11-03 11:01 309 查看
为了保证我们进程运行的安全,并且为了保证我们的循环请求不会因为屏幕变暗,手机睡眠等状态而导致循环停止,推荐大家使用AlarmManager定时唤醒启动服务,执行循环。 

好了,具体看代码。 

一,MainActivity中的主要方法。
package com.mlxing.timerhttp;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//启动Android定时器,并且启动服务
TimerService.getConnet(this);
}

@Override
protected void onDestroy() {
//停止由AlarmManager启动的循环
TimerService.stop(this);
//停止由服务启动的循环
Intent intent = new Intent(this, TimerService.class);
stopService(intent);
super.onDestroy();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

上面没什么好讲的,主要还是让我们来看看TimerService。
package com.mlxing.timerhttp;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import okhttp3.Call;

public class TimerService extends Service {
private boolean pushthread = false;
public TimerService() {
}

@Override
public IBinder onBind(Intent intent) {
Log.d("TimerService", "onBind");
throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TimerService", "onStartCommand");
if (intent.getStringExtra("flags").equals("3")) {
//判断当系统版本大于20,即超过Android5.0时,我们采用线程循环的方式请求。
//当小于5.0时的系统则采用定时唤醒服务的方式执行循环
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion > 20) {
getPushThread();
} else {
getHttp();
}
}
return super.onStartCommand(intent, flags, startId);
}

//循环请求的线程
public void getPushThread() {
pushthread = true;
new Thread(new Runnable() {
@Override
public void run() {
while (pushthread) {
try {
Thread.sleep(3000);
getHttp();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}

//请求网络获取数据
private void getHttp() {
String url = "http://sns.maimaicha.com/api?apikey=b4f4ee31a8b9acc866ef2afb754c33e6&format=json&method=news.getNewsContent&id=1";
OkHttpUtils.get().url(url).build().execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
Log.d("TimerService", "TimerService" + e.toString());
}
@Override
public void onResponse(String response, int id) {
Log.d("TimerService", "response==" + response);
}
});
}

@Override
public void onDestroy() {
pushthread = false;
Log.d("TimerService", "onDestroy");
super.onDestroy();
}

//启动服务和定时器
public static void getConnet(Context mContext) {
try {
Intent intent = new Intent(mContext, TimerService.class);
intent.putExtra("flags", "3");
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion > 20) {
//一般的启动服务的方式
mContext.startService(intent);
} else {
//定时唤醒服务的启动方式
PendingIntent pIntent = PendingIntent.getService(mContext, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) mContext
.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 3000, pIntent);
}
} catch (Exception e) {
e.printStackTrace();
}
}

//停止由AlarmManager启动的循环
public static void stop(Context mContext) {
Intent intent = new Intent(mContext, TimerService.class);
PendingIntent pIntent = PendingIntent.getService(mContext, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) mContext
.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pIntent);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

运行之后结果如下: 



好了,这里就需要重点说明一下,虽然代码里的注释已经写的很清楚了。首先就是系统版本的问题,在Android5.0之后,Android系统对于省电功能这一块做了很大的改善,所以在手机进入睡眠,黑屏等状态时,系统会停止应用的一些不必要的进程。导致一些普通的线程在没有经过保护的情况下自己停止运作了。所以在这里我们在低于5.0版本的时候使用定时唤醒服务AlarmManager 的方式来执行循环,具体的AlarmManager 使用方法和功能网上有很多讲解的地方,在这里我就不细说了。 

不信请看图说话,本人手机亲测小米Note Android6.0系统的效果 



请看圈起来的时间,我在代码中设置的3秒请求一次,然而实际上却是60秒之后,而且手机不同时间还不一样。

还有我这里的网络请求为了节约时间用的是张鸿洋大神的封装的OkHttpUtils。具体链接如下: 
http://blog.csdn.net/lmj623565791/article/details/47911083 

不吹不黑,对于新手来说真的超级方便。今天就说这里吧,别忘了在建项目的时候配置清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mlxing.timerhttp">

<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name=".TimerService"
android:enabled="true"
android:exported="true"></service>
</application>

</manifest>


注意:

getConnet 下的flags 。 可能获取的时候会出现获取不到的情况,程序会直接崩溃了,

这里对获取的地方onStartCommand进行空判处理,提升逻辑严谨性:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "-----------------------onStartCommand----------------------");
if (intent != null){
String flags1 = intent.getStringExtra("flags");
if (!TextUtils.isEmpty(flags1)){
//判断当系统版本大于20,即超过Android5.0时,我们采用线程循环的方式请求。
//当小于5.0时的系统则采用定时唤醒服务的方式执行循环
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion > 20) {
Log.e(TAG, "-----------------------currentapiVersion > 20----------------------");
getPushThread();
} else {
Log.e(TAG, "-----------------------currentapiVersion < 20----------------------");
getHttp();
}
}
}

return super.onStartCommand(intent, flags, startId);
}


参考自:http://blog.csdn.net/hkq463/article/details/51969753
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐