[英]Thread gets killed after few iterations
我正在嘗試創建一個包含服務的應用程序,該服務在設備啟動時啟動,然后記錄一些事件。
manifest.xml中的服務條目
<receiver android:name="com.myservices.BReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
<service android:name="com.myservices.MyService" >
</service>
BReceiver.java
public class BReceiver extends BroadcastReceiver {
private static final String TAG = "BReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive started");
// Main Logging Service
Intent service = new Intent(context, MyService.class);
context.startService(service);
Log.e(TAG, "onReceive ended");
}
}
MService.class
public class MyService extends IntentService {
private static final String TAG = "MyService";
private static final long TIMER = 2000;
public MyService() {
super("MyService");
}
@Override
protected void onHandleIntent(Intent intent) {
startLogginThread();
}
/**
* For logging
*/
private void startLogginThread() {
Thread thread = new Thread() {
public void run() {
while (true) {
try {
// Logging events
myLogger();
Log.e(TAG, "Awake");
// TIMER
Thread.sleep(TIMER);
} catch (Exception e) {
Log.e("MyService", "local Thread error "+ e.toString());
}
}
}
};
thread.start();
}
private void myLogger() {
// Creating new file to store logs.
// Check if SD card is available else use internal memory.
File dir = null;
if (MyServiceUtil.isExternalStorageReadable() && MyServiceUtil.isExternalStorageWritable()) {
// External Memory
File sdCard = Environment.getExternalStorageDirectory();
dir = new File(sdCard.getAbsolutePath() + "/MyLogger");
dir.mkdirs();
} else {
// Internal Memory
dir = getFilesDir();
}
// Rename to txt for reading
File file = new File(dir, "log.txt");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
Log.e(TAG, "Exception :" + e.toString());
}
}
// Printing timestamp in file
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file, true)));
String timeStamp = new SimpleDateFormat("dd.MM.yyyy '-' HH:mm:ss").format(Calendar.getInstance().getTime());
out.println(timeStamp);
// Log Location
out.close();
Log.e("Logggging", timeStamp);
} catch (IOException e) {
Log.e(TAG, "Exception :" + e.toString());
}
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy called");
super.onDestroy();
}
}
結果:僅打印幾次日志,例如6-7次,並將日志存儲在文件中。 下面是日志:
11-16 17:00:02.438: E/BReceiver(3187): onReceive started
11-16 17:00:02.438: E/BReceiver(3187): onReceive ended
11-16 17:00:02.458: E/MyService(3187): onDestroy called
11-16 17:00:02.458: D/MyServiceUtil(3187): isExternalStorageReadable started
11-16 17:00:02.468: D/MyServiceUtil(3187): isExternalStorageWritable started
11-16 17:00:02.468: E/Logggging(3187): 16.11.2014 - 17:00:02
11-16 17:00:02.468: E/MyService(3187): Awake
11-16 17:00:04.468: D/MyServiceUtil(3187): isExternalStorageReadable started
11-16 17:00:04.468: D/MyServiceUtil(3187): isExternalStorageWritable started
11-16 17:00:04.478: E/Logggging(3187): 16.11.2014 - 17:00:04
11-16 17:00:04.478: E/MyService(3187): Awake
11-16 17:00:06.478: D/MyServiceUtil(3187): isExternalStorageReadable started
11-16 17:00:06.488: D/MyServiceUtil(3187): isExternalStorageWritable started
11-16 17:00:06.488: E/Logggging(3187): 16.11.2014 - 17:00:06
11-16 17:00:06.488: E/MyService(3187): Awake
11-16 17:00:08.488: D/MyServiceUtil(3187): isExternalStorageReadable started
11-16 17:00:08.488: D/MyServiceUtil(3187): isExternalStorageWritable started
11-16 17:00:08.488: E/Logggging(3187): 16.11.2014 - 17:00:08
11-16 17:00:08.488: E/MyService(3187): Awake
另外,如果線程已經在運行,我不明白為什么調用onDestroy:
11-16 17:00:02.458:E / MyService(3187):onDestroy被調用
PS-這僅在Kitkat中發生。
要在BroadcastReceiver中執行后台任務,您需要調用goAsync() ,sdk 11+,並在完成后調用PendingResult.finish()
可以由onReceive(Context,Intent)中的應用程序調用此方法,以使其從該函數返回后保持廣播活動。 這不會改變對廣播做出相對響應的期望(在10秒內完成),但是允許實現將與廣播有關的工作移到另一個線程上,以避免由於磁盤IO造成主UI線程故障。
您可以在接收器中移動代碼並使用goAsync,也可以直接在IntentService中運行代碼,因為它與Service不同,它具有自己的后台線程。
更新資料
final PendingResult pendingResult = goAsync();
new Thread() {
public void run() {
while (SOME_CONDITION) {
try {
// Logging events
myLogger();
Log.e(TAG, "Awake");
// TIMER
Thread.sleep(TIMER);
} catch (Exception e) {
Log.e("MyService", "local Thread error "+ e.toString());
}
}
// Finish the broadcast.
pendingResult.finish();
}
}.start();
您對IntentService不太了解。 onHandleIntent的方法是在框架啟動的子線程中調用的,當onHandleIntent完成時,該服務將自行終止,因此原因是您將作業放在了啟動的新線程中。 因此,您應該將代碼放入onHandleIntent中。
while (true) {
try {
// Logging events
myLogger();
Log.e(TAG, "Awake");
// TIMER
Thread.sleep(TIMER);
} catch (Exception e) {
Log.e("MyService", "local Thread error "+ e.toString());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.