android异步线程未执行,关于多线程:当服务在后台运行时,Android异步任务无法正常运行(doInBackground未执行)...
我注意到有時Async任務無法正常運行,實際上它的doInBackground()方法沒有被調用,這種情況主要發生在該活動在后臺運行任何服務時。
例如,當音樂在帶有服務的后臺運行時,Async任務不會在后臺解析XML,因為它的doInBackground當時不起作用,并且進度Dialog或progressBar一直旋轉。
我讀過幾篇文章,AsyncTask.THREAD_POOL_EXECUTOR可以幫助解決以下問題:
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new Test().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new Test().execute();
}
但這對我的情況沒有幫助。在上述實施后存在相同的問題。
在這里,我僅提供一些示例代碼來了解我在做什么:
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
}
}
}
通常,此方法運行良好,但在Service在背景音樂中運行時掛起(我的意思是在播放音樂時)。
我沒有得到這個異步任務問題背后的確切原因。
在這種情況下,手動線程實現會有所幫助嗎?
好吧,我認為問題是因為" Service在主線程中運行,因此當它運行時,它會阻止我的AsyncTask運行"。因此,我認為,如果我們可以在后臺線程中運行Service,那將有所幫助。這就是為什么我嘗試使用IntentService在單獨的線程中運行服務,但我對此表示懷疑……如果IntentService可以像Service一樣無限期地運行,并且IntentService也會阻塞AsyncTask幾次。
因此,我認為它不能100%完美地解決此類問題。
誰能幫助我解決此問題并了解完整的情況。
提前致謝。
您要擴展Service還是IntentService
我正在使用服務在后臺播放音樂
異步任務應該工作。你在某個地方犯了錯誤。
我非常確定我在實現Asynctask時沒有犯任何錯誤,因為通常情況下(在大多數情況下)它可以正常工作,但是當音樂在后臺播放時,progressBar會不斷旋轉。一件事,我在onResume()方法中調用AsyncTask,因為每次活動進入前臺時我都需要刷新數據。它會影響AsyncTask的性能嗎。我不這樣認為,但請告知是否存在任何問題。
服務將在主線程中運行。因此請嘗試使用IntentService而不是Service,因為IntentService將在單獨的線程中運行
使用IntentService代替服務會影響我的應用程序的性能嗎?因為我正在使用bindService播放音樂,也使用.aidl,所以要使用IntentService而不是Service,我是否需要在Current Service類中進行其他更改,或者可以繼續使用同一類,只需將基本Service類替換為IntentService ..?
不,我認為這不會降低性能。請參閱IntentService上的一些示例
好的,但是由于我在Binder中使用服務,所以我認為IntentService不可能做到這一點!
在彈出進度欄并啟動AsyncTask的地方顯示代碼。
@yorkw我已經更新了我的代碼,請對其進行檢查,如果我在此代碼中犯了一些錯誤,請告訴我。
您在說什么音樂播放器?是你寫的嗎?
@JustinBreitfeller是的,當用戶從歌曲列表中選擇任何歌曲時,我正在后臺播放音樂。
您如何播放音樂?您是否正在使用長期運行的AsyncTask?
嘗試將android:process =":remote"添加到服務中,并檢查是否調用了asynctask,如果您在其他進程中運行服務,則可能不會出現這種情況
有時,與IntentService相比,您可能希望對服務的生命周期有更多的控制,在這種情況下,您只需在服務中創建線程并在其中運行后臺代碼即可。實際上,更具體地說,創建一個包含Looper的HandlerThread,以便您可以使用標準android方法在主線程和后臺線程之間進行通信(消息)。
在這里回答
這是一個提示,我如何最終解決我的問題::
1)我使用IntentService而不是Service,因為Service在mainThread中運行,而IntentService在與mainThread不同的單獨線程中運行,以確保后臺Service不會影響當前任務。 另外,我正在使用AIDL在我的UI和后臺線程之間進行通信(該服務已經在Service上工作了,所以本部分沒有新內容)。
2)我使用了無痛線程而不是AsyncTask,我在onDestroy()方法中中斷了該線程,以確保該線程確實無限期地繼續。
應用程序的性能似乎比現在早得多。
希望這也會對其他人有所幫助:)
這不公平。 人們提出了所有解決方案…
@ user1521536:您說的很對,人們向我提出了解決方案,但是沒有一個解決方案包含了我所應用的兩個解決方案提示,因此只是為了幫助其他人,我將它們組合在一起以獲得更好的解決方案。
I noticed that sometimes Async task does not work properly , Actually
its doInBackground() method does not get called , this happens mostly
您知道一次只能執行AsyncTasks的限制嗎?我曾經遇到一個任務無法正常啟動/正常工作的問題,這是因為我超過了這個數字。檢查Android AsyncTask線程限制?有關該主題的更多信息。
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
無論如何,您將要在服務中執行的操作應在自己的線程中運行。這樣,您可以確定什么都不會被阻塞。例如,如果您要填充一些東西,可以使用接收器。
希望我能有所幫助...
閱讀這里發布的所有問題和答案。糾正我,如果我錯了,您的情況是您正在解析xml并獲取歌曲列表,并且當用戶選擇任何要使用服務播放的歌曲時正確嗎?
如果方案是正確的,那么我們可以以更簡單的方式實施它。
在"活動"中,onResume()方法解析XML文件并獲取歌曲列表并更新列表視圖(此處不啟動與服務相關的任何操作)
當用戶單擊歌曲,然后有意地將特定的鍵/字符串傳遞給服務并啟動服務
與常規媒體API一樣,在服務的OnStartCommand()方法中獲取標識符并開始播放歌曲
這實際上將為您完成工作。
關于問題
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new Test().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new Test().execute();
}
這是針對AsyncTask在不同版本的Android上的不同行為。
查看您的代碼,在Activity中,您正在初始化服務,因此該服務在后臺運行,而沒有做任何有成果的事情。
當用戶單擊播放時,您將在此處調用服務的播放功能,從而造成問題。
因此要從Activity調用服務功能,您應該糾正未提及的AIDL。如果您已經寫過,那應該是完美的。
但是這里的建議是將歌曲ID傳遞給服務,并且應該從服務中播放,而不應該在活動中調用服務的功能。
如果要在活動的onResume中更新歌曲列表,則必須編寫AIDL并完成方案
希望這會有所幫助。
謝謝你的寶貴建議,但是我已經使用IntentService而不是Service來實現,并且用Painless線程代替了Async任務,并且效果很好:)
我已經在測試項目中實現了您的方案。 因此,您甚至可以使用AIDL。 如果您發現ans pls接受任何一個ans。
我認為問題是在上一個完成之前開始另一個GetData AsyncTask。在執行另一任務之前,請確保先前的任務已完成。為此,請使用以下代碼:
// 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();
}
另外,請確保您具有運行任務的參考。您可以在應用程序運行時使用Application類的子類來執行此操作,或者覆蓋onSaveInstanceState(Bundle outState)
并在onCreate(Bundle savedInstanceState)中收到對其的引用。
根據Android開發人員AsyncTask文檔的"線程規則"部分,必須在UI線程上創建并啟動AsyncTask,因此,如果從Service中的后臺線程啟動AsyncTask,則可能會導致錯誤行為。
http://developer.android.com/reference/android/os/AsyncTask.html
對于投票否決的人,我是否可以要求澄清為何投票? 據我對用戶問題的理解,除非我只是用后臺線程或IntentService誤插入有關Service的底層語句,否則他是在intent服務中啟動該服務的,因此不會在UI線程上運行。
通常,您真的不應該使用AsyncTasks :)這里有一個很好的解釋。想一想,如果用戶在任務運行時旋轉設備,將會發生什么情況。重新創建了活動,但任務在后臺運行,并保留了對"舊"活動的引用。有多種方法可以解決此問題,并且肯定在某些情況下AsyncTasks是正確的方法。
但是,您確實應該考慮切換到裝載機,或者(如果您喜歡冒險的話)嘗試RoboSpice :)
總結
以上是生活随笔為你收集整理的android异步线程未执行,关于多线程:当服务在后台运行时,Android异步任务无法正常运行(doInBackground未执行)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android7.1 shotcuts,
- 下一篇: HTML怎么限制每行字数,JS实现每行固