我可以在 android 中创建一个后台服务,它可以在特定时间完成工作后进入休眠状态吗? 有这方面的想法请指导。
最佳答案
作为初学者的好问题,但是为此您需要了解 Intent Service。
<强>1。什么是 IntentService?
- IntentService 是 android.app.Service 类的子类。一个声明 Intent 服务允许处理长时间运行的任务而不影响 应用程序 UI 线程。这不受任何 Activity 的约束,因此,它 不会因 Activity 生命周期中的任何更改而受到影响。一次 IntentService 启动,它使用 worker 处理每个 Intent 线程并在它用完工作时自行停止。
- 使用 IntentService,任何时候只能处理一个请求 单点时间。如果您请求另一个任务,那么新的 作业将等到上一个作业完成。这意味着 IntentService 处理请求。
- 使用 IntentService 声明的任务不能被中断
<强>2。创建一个 IntentService:
我们将创建一个 IntentService 来从服务器下载数据。下载完成后,响应将发送回 Activity 。让我们创建一个新类 DownloadService.java 并从 android.app.IntentService 扩展它。现在让我们覆盖 onHandleIntent() 方法。
public class DownloadService extends IntentService {
public static final int STATUS_RUNNING = 0;
public static final int STATUS_FINISHED = 1;
public static final int STATUS_ERROR = 2;
private static final String TAG = "DownloadService";
public DownloadService() {
super(DownloadService.class.getName());
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "Service Started!");
final ResultReceiver receiver = intent.getParcelableExtra("receiver");
String url = intent.getStringExtra("url");
Bundle bundle = new Bundle();
if (!TextUtils.isEmpty(url)) {
/* Update UI: Download Service is Running */
receiver.send(STATUS_RUNNING, Bundle.EMPTY);
try {
String[] results = downloadData(url);
/* Sending result back to activity */
if (null != results && results.length > 0) {
bundle.putStringArray("result", results);
receiver.send(STATUS_FINISHED, bundle);
}
} catch (Exception e) {
/* Sending error message back to activity */
bundle.putString(Intent.EXTRA_TEXT, e.toString());
receiver.send(STATUS_ERROR, bundle);
}
}
Log.d(TAG, "Service Stopping!");
this.stopSelf();
}
private String[] downloadData(String requestUrl) throws IOException, DownloadException {
InputStream inputStream = null;
HttpURLConnection urlConnection = null;
/* forming th java.net.URL object */
URL url = new URL(requestUrl);
urlConnection = (HttpURLConnection) url.openConnection();
/* optional request header */
urlConnection.setRequestProperty("Content-Type", "application/json");
/* optional request header */
urlConnection.setRequestProperty("Accept", "application/json");
/* for Get request */
urlConnection.setRequestMethod("GET");
int statusCode = urlConnection.getResponseCode();
/* 200 represents HTTP OK */
if (statusCode == 200) {
inputStream = new BufferedInputStream(urlConnection.getInputStream());
String response = convertInputStreamToString(inputStream);
String[] results = parseResult(response);
return results;
} else {
throw new DownloadException("Failed to fetch data!!");
}
}
private String convertInputStreamToString(InputStream inputStream) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
String result = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
/* Close Stream */
if (null != inputStream) {
inputStream.close();
}
return result;
}
private String[] parseResult(String result) {
String[] blogTitles = null;
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.optJSONArray("posts");
blogTitles = new String[posts.length()];
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
String title = post.optString("title");
blogTitles[i] = title;
}
} catch (JSONException e) {
e.printStackTrace();
}
return blogTitles;
}
public class DownloadException extends Exception {
public DownloadException(String message) {
super(message);
}
public DownloadException(String message, Throwable cause) {
super(message, cause);
}
}
}
3.工作原理
DownloadService 类扩展了 IntentService 并覆盖了 onHandleIntent() 方法。在 onHandleIntent() 方法中,我们将执行网络请求以从服务器下载数据
在它从服务器下载数据之前,请求是从 bundle 中获取的。我们的 Activity 将在启动时将此数据作为额外发送
一旦下载成功,我们将通过 ResultReceiver 将响应发送回 Activity
对于任何异常或错误,我们将通过 ResultReceiver 将错误响应传回 Activity 。
我们已经声明了自定义异常类 DownloadException 来处理我们所有的自定义错误消息。你可以这样做
<强>4。在 list 中声明服务
与服务一样,IntentService 也需要在您的应用程序 list 中有一个条目。提供元素条目并声明您使用的所有 IntentServices。此外,当我们执行从互联网下载数据的操作时,我们将请求 android.permission.INTERNET 权限。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.javatechig.intentserviceexample">
<!-- Internet permission, as we are accessing data from server -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MyActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Declaring Service in Manifest -->
<service
android:name=".DownloadService"
android:exported="false" />
</application>
</manifest>
6.向 IntentService 发送工作请求
要启动DownloadService下载数据,必须创建一个显式的Intent,并在其中添加所有的请求参数。可以通过调用 startService() 方法来启动服务。您可以从 Activity 或 Fragment 启动 IntentService。
这里额外的 DownloadResultReceiver 是什么,嗯?请记住,我们必须将下载请求的结果从服务传递到 Activity 。这将通过 ResultReceiver 完成。
/* Starting Download Service */
mReceiver = new DownloadResultReceiver(new Handler());
mReceiver.setReceiver(this);
Intent intent = new Intent(Intent.ACTION_SYNC, null, this, DownloadService.class);
/* Send optional extras to Download IntentService */
intent.putExtra("url", url);
intent.putExtra("receiver", mReceiver);
intent.putExtra("requestId", 101);
startService(intent);
只需按照您的要求进行更改即可。 记住***** IntentService 启动后,它会使用工作线程处理每个 Intent,并在它用完工作时自行停止。
关于android - android中的可 sleep 后台服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33938695/