稳定的闹钟服务定时循环请求网络接口(可做类似即时通讯或者推送功能)
2017-11-03 11:01
309 查看
为了保证我们进程运行的安全,并且为了保证我们的循环请求不会因为屏幕变暗,手机睡眠等状态而导致循环停止,推荐大家使用AlarmManager定时唤醒启动服务,执行循环。
好了,具体看代码。
一,MainActivity中的主要方法。
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。
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
不吹不黑,对于新手来说真的超级方便。今天就说这里吧,别忘了在建项目的时候配置清单文件
注意:
getConnet 下的flags 。 可能获取的时候会出现获取不到的情况,程序会直接崩溃了,
这里对获取的地方onStartCommand进行空判处理,提升逻辑严谨性:
参考自:http://blog.csdn.net/hkq463/article/details/51969753
好了,具体看代码。
一,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
相关文章推荐
- 稳定的定时循环请求网络接口(可做类似即时通讯或者推送功能)
- Python循环定时服务功能(类似contrab)
- Python循环定时服务功能(相似contrab)
- 使用afnetworking和网络服务接口及soap发送并接收http/https请求:
- 17 Jquer定时刷新以及循环遍历功能和ajax 的异步请求数据
- 十年一遇的奇葩故障--Windows网络编程接口故障:telnet显示无法加载或初始化请求的服务提供程序
- 通用JS工具类封装——网络数据请求功能、获取服务端接口 url、参数功能
- PL/SQL中使用EXISTS:使用LOOP循环替代或者SELECT实现类似的功能:
- Linux服务器 CentOS 6系列最小化安装优化脚本详解02————修改history记录、定时校正服务器时间、停止IPv6网络服务、调整最大文件打开数、关闭写磁盘I/O功能、配置SSH服务
- go 提供网络服务功能
- mfc小工具开发之定时闹钟之---功能介绍
- smarty-smarty模板中类似for循环功能的实现代码
- 封装网络请求,下载,上传功能
- Android Asynchronous Http Client-Android异步网络请求客户端接口
- 为什么axios请求接口会发起两次请求(OPTIONS 和POST或者GET)
- 【读书笔记】iOS网络-异步请求与运行循环
- retrofit2.0增加先读缓存后请求网络的功能
- java图片插入窗口定时循环移动或者按鼠标位置移动
- 网络服务程序接口Web services APIs
- 【大数据技术干货】阿里云伏羲(fuxi)调度器FuxiMaster功能简介(三) 针对在线服务的资源强稳定