android异步线程未执行,关于多线程:当服务在后台运行时,Android异步任务无法正常运行(doInBackground未执行)...
我注意到有時(shí)Async任務(wù)無(wú)法正常運(yùn)行,實(shí)際上它的doInBackground()方法沒(méi)有被調(diào)用,這種情況主要發(fā)生在該活動(dòng)在后臺(tái)運(yùn)行任何服務(wù)時(shí)。
例如,當(dāng)音樂(lè)在帶有服務(wù)的后臺(tái)運(yùn)行時(shí),Async任務(wù)不會(huì)在后臺(tái)解析XML,因?yàn)樗膁oInBackground當(dāng)時(shí)不起作用,并且進(jìn)度Dialog或progressBar一直旋轉(zhuǎn)。
我讀過(guò)幾篇文章,AsyncTask.THREAD_POOL_EXECUTOR可以幫助解決以下問(wèn)題:
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new Test().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new Test().execute();
}
但這對(duì)我的情況沒(méi)有幫助。在上述實(shí)施后存在相同的問(wèn)題。
在這里,我僅提供一些示例代碼來(lái)了解我在做什么:
public class TestAct extends Activity {
ImageButton play,forward,backward;
private ListView mList;
// many more variables
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
//binding the service here
// start service is called
init();
}
private void init(){
play=(ImageButton)findViewById(R.id.playBtn);
forward=(ImageButton)findViewById(R.id.forward);
backward=(ImageButton)findViewById(R.id.backward);
mList=(ListView)findViewById(R.id.list);
new GetData().execute();
play.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// calling the play() method of ServiceConnection here
}
});
// adding header to Listview
// other code and click listeners
}
class GetData extends AsyncTask{
@Override
protected void onPreExecute() {
super.onPreExecute();
// starting the progress Bar
// initializing the Arraylist,Maps etc
}
@Override
protected Void doInBackground(Void... params) {
//parsing the XML here
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// stop the ProgressBar
// Updating my UI here
// setting Adapter for ListView
}
}
}
通常,此方法運(yùn)行良好,但在Service在背景音樂(lè)中運(yùn)行時(shí)掛起(我的意思是在播放音樂(lè)時(shí))。
我沒(méi)有得到這個(gè)異步任務(wù)問(wèn)題背后的確切原因。
在這種情況下,手動(dòng)線(xiàn)程實(shí)現(xiàn)會(huì)有所幫助嗎?
好吧,我認(rèn)為問(wèn)題是因?yàn)?#34; Service在主線(xiàn)程中運(yùn)行,因此當(dāng)它運(yùn)行時(shí),它會(huì)阻止我的AsyncTask運(yùn)行"。因此,我認(rèn)為,如果我們可以在后臺(tái)線(xiàn)程中運(yùn)行Service,那將有所幫助。這就是為什么我嘗試使用IntentService在單獨(dú)的線(xiàn)程中運(yùn)行服務(wù),但我對(duì)此表示懷疑……如果IntentService可以像Service一樣無(wú)限期地運(yùn)行,并且IntentService也會(huì)阻塞AsyncTask幾次。
因此,我認(rèn)為它不能100%完美地解決此類(lèi)問(wèn)題。
誰(shuí)能幫助我解決此問(wèn)題并了解完整的情況。
提前致謝。
您要擴(kuò)展Service還是IntentService
我正在使用服務(wù)在后臺(tái)播放音樂(lè)
異步任務(wù)應(yīng)該工作。你在某個(gè)地方犯了錯(cuò)誤。
我非常確定我在實(shí)現(xiàn)Asynctask時(shí)沒(méi)有犯任何錯(cuò)誤,因?yàn)橥ǔG闆r下(在大多數(shù)情況下)它可以正常工作,但是當(dāng)音樂(lè)在后臺(tái)播放時(shí),progressBar會(huì)不斷旋轉(zhuǎn)。一件事,我在onResume()方法中調(diào)用AsyncTask,因?yàn)槊看位顒?dòng)進(jìn)入前臺(tái)時(shí)我都需要刷新數(shù)據(jù)。它會(huì)影響AsyncTask的性能嗎。我不這樣認(rèn)為,但請(qǐng)告知是否存在任何問(wèn)題。
服務(wù)將在主線(xiàn)程中運(yùn)行。因此請(qǐng)嘗試使用IntentService而不是Service,因?yàn)镮ntentService將在單獨(dú)的線(xiàn)程中運(yùn)行
使用IntentService代替服務(wù)會(huì)影響我的應(yīng)用程序的性能嗎?因?yàn)槲艺谑褂胋indService播放音樂(lè),也使用.aidl,所以要使用IntentService而不是Service,我是否需要在Current Service類(lèi)中進(jìn)行其他更改,或者可以繼續(xù)使用同一類(lèi),只需將基本Service類(lèi)替換為IntentService ..?
不,我認(rèn)為這不會(huì)降低性能。請(qǐng)參閱IntentService上的一些示例
好的,但是由于我在Binder中使用服務(wù),所以我認(rèn)為IntentService不可能做到這一點(diǎn)!
在彈出進(jìn)度欄并啟動(dòng)AsyncTask的地方顯示代碼。
@yorkw我已經(jīng)更新了我的代碼,請(qǐng)對(duì)其進(jìn)行檢查,如果我在此代碼中犯了一些錯(cuò)誤,請(qǐng)告訴我。
您在說(shuō)什么音樂(lè)播放器?是你寫(xiě)的嗎?
@JustinBreitfeller是的,當(dāng)用戶(hù)從歌曲列表中選擇任何歌曲時(shí),我正在后臺(tái)播放音樂(lè)。
您如何播放音樂(lè)?您是否正在使用長(zhǎng)期運(yùn)行的AsyncTask?
嘗試將android:process =":remote"添加到服務(wù)中,并檢查是否調(diào)用了asynctask,如果您在其他進(jìn)程中運(yùn)行服務(wù),則可能不會(huì)出現(xiàn)這種情況
有時(shí),與IntentService相比,您可能希望對(duì)服務(wù)的生命周期有更多的控制,在這種情況下,您只需在服務(wù)中創(chuàng)建線(xiàn)程并在其中運(yùn)行后臺(tái)代碼即可。實(shí)際上,更具體地說(shuō),創(chuàng)建一個(gè)包含Looper的HandlerThread,以便您可以使用標(biāo)準(zhǔn)android方法在主線(xiàn)程和后臺(tái)線(xiàn)程之間進(jìn)行通信(消息)。
在這里回答
這是一個(gè)提示,我如何最終解決我的問(wèn)題::
1)我使用IntentService而不是Service,因?yàn)镾ervice在mainThread中運(yùn)行,而IntentService在與mainThread不同的單獨(dú)線(xiàn)程中運(yùn)行,以確保后臺(tái)Service不會(huì)影響當(dāng)前任務(wù)。 另外,我正在使用AIDL在我的UI和后臺(tái)線(xiàn)程之間進(jìn)行通信(該服務(wù)已經(jīng)在Service上工作了,所以本部分沒(méi)有新內(nèi)容)。
2)我使用了無(wú)痛線(xiàn)程而不是AsyncTask,我在onDestroy()方法中中斷了該線(xiàn)程,以確保該線(xiàn)程確實(shí)無(wú)限期地繼續(xù)。
應(yīng)用程序的性能似乎比現(xiàn)在早得多。
希望這也會(huì)對(duì)其他人有所幫助:)
這不公平。 人們提出了所有解決方案…
@ user1521536:您說(shuō)的很對(duì),人們向我提出了解決方案,但是沒(méi)有一個(gè)解決方案包含了我所應(yīng)用的兩個(gè)解決方案提示,因此只是為了幫助其他人,我將它們組合在一起以獲得更好的解決方案。
I noticed that sometimes Async task does not work properly , Actually
its doInBackground() method does not get called , this happens mostly
您知道一次只能執(zhí)行AsyncTasks的限制嗎?我曾經(jīng)遇到一個(gè)任務(wù)無(wú)法正常啟動(dòng)/正常工作的問(wèn)題,這是因?yàn)槲页^(guò)了這個(gè)數(shù)字。檢查Android AsyncTask線(xiàn)程限制?有關(guān)該主題的更多信息。
when any service run in background for that activity. For Example ,
when music runs in background with service, the Async task does not
parse XML in background as its doInBackground does not work that time
and the progress Dialog or progressBar kept spinning.
您是否檢查了死鎖的可能性(特別是如果使用的是wait()和notify())?
Well, I think the problem is because"Service runs in main thread so
when it runs, it blocks my AsyncTask to run"... So I think If we can
run Service in background thread then that can help . Thats why I
無(wú)論如何,您將要在服務(wù)中執(zhí)行的操作應(yīng)在自己的線(xiàn)程中運(yùn)行。這樣,您可以確定什么都不會(huì)被阻塞。例如,如果您要填充一些東西,可以使用接收器。
希望我能有所幫助...
閱讀這里發(fā)布的所有問(wèn)題和答案。糾正我,如果我錯(cuò)了,您的情況是您正在解析xml并獲取歌曲列表,并且當(dāng)用戶(hù)選擇任何要使用服務(wù)播放的歌曲時(shí)正確嗎?
如果方案是正確的,那么我們可以以更簡(jiǎn)單的方式實(shí)施它。
在"活動(dòng)"中,onResume()方法解析XML文件并獲取歌曲列表并更新列表視圖(此處不啟動(dòng)與服務(wù)相關(guān)的任何操作)
當(dāng)用戶(hù)單擊歌曲,然后有意地將特定的鍵/字符串傳遞給服務(wù)并啟動(dòng)服務(wù)
與常規(guī)媒體API一樣,在服務(wù)的OnStartCommand()方法中獲取標(biāo)識(shí)符并開(kāi)始播放歌曲
這實(shí)際上將為您完成工作。
關(guān)于問(wèn)題
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new Test().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new Test().execute();
}
這是針對(duì)AsyncTask在不同版本的Android上的不同行為。
查看您的代碼,在Activity中,您正在初始化服務(wù),因此該服務(wù)在后臺(tái)運(yùn)行,而沒(méi)有做任何有成果的事情。
當(dāng)用戶(hù)單擊播放時(shí),您將在此處調(diào)用服務(wù)的播放功能,從而造成問(wèn)題。
因此要從Activity調(diào)用服務(wù)功能,您應(yīng)該糾正未提及的AIDL。如果您已經(jīng)寫(xiě)過(guò),那應(yīng)該是完美的。
但是這里的建議是將歌曲ID傳遞給服務(wù),并且應(yīng)該從服務(wù)中播放,而不應(yīng)該在活動(dòng)中調(diào)用服務(wù)的功能。
如果要在活動(dòng)的onResume中更新歌曲列表,則必須編寫(xiě)AIDL并完成方案
希望這會(huì)有所幫助。
謝謝你的寶貴建議,但是我已經(jīng)使用IntentService而不是Service來(lái)實(shí)現(xiàn),并且用Painless線(xiàn)程代替了Async任務(wù),并且效果很好:)
我已經(jīng)在測(cè)試項(xiàng)目中實(shí)現(xiàn)了您的方案。 因此,您甚至可以使用AIDL。 如果您發(fā)現(xiàn)ans pls接受任何一個(gè)ans。
我認(rèn)為問(wèn)題是在上一個(gè)完成之前開(kāi)始另一個(gè)GetData AsyncTask。在執(zhí)行另一任務(wù)之前,請(qǐng)確保先前的任務(wù)已完成。為此,請(qǐng)使用以下代碼:
// make sure we don't collide with another pending AsyncTask
if (getDataTask == null || getDataTask.getStatus() == AsyncTask.Status.FINISHED || getDataTask.isCancelled()) {
getDataTask= new GetData();
getDataTask.execute();
}
另外,請(qǐng)確保您具有運(yùn)行任務(wù)的參考。您可以在應(yīng)用程序運(yùn)行時(shí)使用Application類(lèi)的子類(lèi)來(lái)執(zhí)行此操作,或者覆蓋onSaveInstanceState(Bundle outState)
并在onCreate(Bundle savedInstanceState)中收到對(duì)其的引用。
根據(jù)Android開(kāi)發(fā)人員AsyncTask文檔的"線(xiàn)程規(guī)則"部分,必須在UI線(xiàn)程上創(chuàng)建并啟動(dòng)AsyncTask,因此,如果從Service中的后臺(tái)線(xiàn)程啟動(dòng)AsyncTask,則可能會(huì)導(dǎo)致錯(cuò)誤行為。
http://developer.android.com/reference/android/os/AsyncTask.html
對(duì)于投票否決的人,我是否可以要求澄清為何投票? 據(jù)我對(duì)用戶(hù)問(wèn)題的理解,除非我只是用后臺(tái)線(xiàn)程或IntentService誤插入有關(guān)Service的底層語(yǔ)句,否則他是在intent服務(wù)中啟動(dòng)該服務(wù)的,因此不會(huì)在UI線(xiàn)程上運(yùn)行。
通常,您真的不應(yīng)該使用AsyncTasks :)這里有一個(gè)很好的解釋。想一想,如果用戶(hù)在任務(wù)運(yùn)行時(shí)旋轉(zhuǎn)設(shè)備,將會(huì)發(fā)生什么情況。重新創(chuàng)建了活動(dòng),但任務(wù)在后臺(tái)運(yùn)行,并保留了對(duì)"舊"活動(dòng)的引用。有多種方法可以解決此問(wèn)題,并且肯定在某些情況下AsyncTasks是正確的方法。
但是,您確實(shí)應(yīng)該考慮切換到裝載機(jī),或者(如果您喜歡冒險(xiǎn)的話(huà))嘗試RoboSpice :)
總結(jié)
以上是生活随笔為你收集整理的android异步线程未执行,关于多线程:当服务在后台运行时,Android异步任务无法正常运行(doInBackground未执行)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android7.1 shotcuts,
- 下一篇: android安装类型,Android