设备关闭时的 IntentService onHandleIntent 行为
IntentService onHandleIntent behaviour on device shutdown
设备关闭时 onHandleIntent 的行为是什么?
我知道在 IntentService 上,只要 onHandleIntent 没有完成它的工作,服务就会保持 运行。
所以开始考虑它是关于设备关闭时服务行为的一般问题,一旦我们再次启动设备,它们会 "wake" 启动吗?
如果没有,有办法吗?我希望我的 intentservice 保持 运行 直到 onHandleIntent 完成,无论发生什么。
编辑:
我将添加我的代码以便更好地理解。
我试图在 SQLite 上保存请求并保持 运行 直到 table 为空,然后服务将关闭。
所以万一设备关机,我仍然会从关机前的同一个地方继续。
P.S - 我尝试使用 executor 以获得更好的性能(这是一个测试,尚未证明)
如果有人有更好的建议,我很乐意听取他们的意见,因为我是这个主题的新手
onHandleIntent
@Override
protected void onHandleIntent(Intent intent) {
helper = new DBHelper(getApplicationContext());
executor = Executors.newFixedThreadPool(5);
File file;
Log.e("requestsExists",helper.requestsExists()+"");
while (helper.requestsExists()) {
ArrayList<String> requestArr = helper.getRequestsToExcute(5);
//checks if the DB requests exists
if (!requestArr.isEmpty()) {
//execute them and delete the DB entry
for(int i = 0; i < requestArr.size(); i++) {
file = new File(requestArr.get(i));
Log.e("file",file.toString());
Future<String> future = executor.submit(new MyThread(file,getApplicationContext()));
Log.e("future object", future.toString());
try {
long idToDelete = Long.parseLong(future.get());
Log.e("THREAD ANSWER", future.get() + "");
helper.deleteRequest(idToDelete);
} catch (InterruptedException e) {
Log.e("future try", "");
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
executor.shutdown();
}
我的线程
public class MyThread implements Callable {
private File _file;
private Context context;
private DBHelper helper;
public MyThread(File file, Context context) {
this._file = file;
this.context = context;
}
@Override
public String call() throws Exception {
HttpClient client = Utility.getNewHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost post = new HttpPost("http://192.168.9.62/mobile_api/timeline/moment/upload");
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
FileBody fileBody = new FileBody(_file);
builder.addPart("content", fileBody);
builder.addPart("type", new StringBody("file", ContentType.TEXT_PLAIN));
builder.addPart("title", new StringBody("service test", ContentType.TEXT_PLAIN));
builder.addPart("userType", new StringBody("user", ContentType.TEXT_PLAIN));
builder.addPart("uid", new StringBody(MyInfiActivity.friends_uid, ContentType.TEXT_PLAIN));
builder.addPart("momentId", new StringBody("1", ContentType.TEXT_PLAIN));
builder.addPart("storyId", new StringBody("8", ContentType.TEXT_PLAIN));
Utility.addCookiesToPost(post);
post.setEntity(builder.build());
client.execute(post, localContext);
} catch (IOException e) {
Log.e("Callable try", post.toString());
}
return "1";
}
}
我会尽量逐条回答你的问题
设备关闭时 onHandleIntent 的行为是什么?
由于设备将完全关闭,所有服务都将被强制停止,包括您的 IntentService。
您可以订阅 ACTION_SHUTDOWN 以了解设备何时关闭并在它真正关闭之前做一些事情。
public class ShutdownHandlerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Handle here, but don't make actions that takes too long
}
}
此外,您还必须将其添加到清单中
<receiver android:name=".ShutdownHandlerReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
</intent-filter>
</receiver>
一旦我们再次启动设备,它们会"wake"吗?
不,他们不会,因为他们已经处理过类似的东西,但您可以订阅 ACTION_BOOT_COMPLETED 以了解设备何时准备就绪。来自文档:
Broadcast Action: This is broadcast once, after the system has
finished booting. It can be used to perform application-specific
initialization, such as installing alarms. You must hold the
RECEIVE_BOOT_COMPLETED permission in order to receive this broadcast.
public class BootedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Handle here, you can start again your stopped intentservices
}
}
并且在清单中:
<receiver android:name=".BootedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
然后您可以重新启动意向服务队列,我想这是最好的方法。
AFAIK,如果当时 运行 设备关闭,您的 IntentService 将停止,系统不会在启动时自动为我们启动它,我们必须自己做。
有关操作方法,请参阅 this。
设备关闭时 onHandleIntent 的行为是什么?
我知道在 IntentService 上,只要 onHandleIntent 没有完成它的工作,服务就会保持 运行。
所以开始考虑它是关于设备关闭时服务行为的一般问题,一旦我们再次启动设备,它们会 "wake" 启动吗?
如果没有,有办法吗?我希望我的 intentservice 保持 运行 直到 onHandleIntent 完成,无论发生什么。
编辑: 我将添加我的代码以便更好地理解。 我试图在 SQLite 上保存请求并保持 运行 直到 table 为空,然后服务将关闭。 所以万一设备关机,我仍然会从关机前的同一个地方继续。 P.S - 我尝试使用 executor 以获得更好的性能(这是一个测试,尚未证明) 如果有人有更好的建议,我很乐意听取他们的意见,因为我是这个主题的新手
onHandleIntent
@Override
protected void onHandleIntent(Intent intent) {
helper = new DBHelper(getApplicationContext());
executor = Executors.newFixedThreadPool(5);
File file;
Log.e("requestsExists",helper.requestsExists()+"");
while (helper.requestsExists()) {
ArrayList<String> requestArr = helper.getRequestsToExcute(5);
//checks if the DB requests exists
if (!requestArr.isEmpty()) {
//execute them and delete the DB entry
for(int i = 0; i < requestArr.size(); i++) {
file = new File(requestArr.get(i));
Log.e("file",file.toString());
Future<String> future = executor.submit(new MyThread(file,getApplicationContext()));
Log.e("future object", future.toString());
try {
long idToDelete = Long.parseLong(future.get());
Log.e("THREAD ANSWER", future.get() + "");
helper.deleteRequest(idToDelete);
} catch (InterruptedException e) {
Log.e("future try", "");
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
executor.shutdown();
}
我的线程
public class MyThread implements Callable {
private File _file;
private Context context;
private DBHelper helper;
public MyThread(File file, Context context) {
this._file = file;
this.context = context;
}
@Override
public String call() throws Exception {
HttpClient client = Utility.getNewHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost post = new HttpPost("http://192.168.9.62/mobile_api/timeline/moment/upload");
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
FileBody fileBody = new FileBody(_file);
builder.addPart("content", fileBody);
builder.addPart("type", new StringBody("file", ContentType.TEXT_PLAIN));
builder.addPart("title", new StringBody("service test", ContentType.TEXT_PLAIN));
builder.addPart("userType", new StringBody("user", ContentType.TEXT_PLAIN));
builder.addPart("uid", new StringBody(MyInfiActivity.friends_uid, ContentType.TEXT_PLAIN));
builder.addPart("momentId", new StringBody("1", ContentType.TEXT_PLAIN));
builder.addPart("storyId", new StringBody("8", ContentType.TEXT_PLAIN));
Utility.addCookiesToPost(post);
post.setEntity(builder.build());
client.execute(post, localContext);
} catch (IOException e) {
Log.e("Callable try", post.toString());
}
return "1";
}
}
我会尽量逐条回答你的问题
设备关闭时 onHandleIntent 的行为是什么?
由于设备将完全关闭,所有服务都将被强制停止,包括您的 IntentService。
您可以订阅 ACTION_SHUTDOWN 以了解设备何时关闭并在它真正关闭之前做一些事情。
public class ShutdownHandlerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Handle here, but don't make actions that takes too long
}
}
此外,您还必须将其添加到清单中
<receiver android:name=".ShutdownHandlerReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
</intent-filter>
</receiver>
一旦我们再次启动设备,它们会"wake"吗?
不,他们不会,因为他们已经处理过类似的东西,但您可以订阅 ACTION_BOOT_COMPLETED 以了解设备何时准备就绪。来自文档:
Broadcast Action: This is broadcast once, after the system has finished booting. It can be used to perform application-specific initialization, such as installing alarms. You must hold the RECEIVE_BOOT_COMPLETED permission in order to receive this broadcast.
public class BootedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Handle here, you can start again your stopped intentservices
}
}
并且在清单中:
<receiver android:name=".BootedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
然后您可以重新启动意向服务队列,我想这是最好的方法。
AFAIK,如果当时 运行 设备关闭,您的 IntentService 将停止,系统不会在启动时自动为我们启动它,我们必须自己做。
有关操作方法,请参阅 this。