我的MainActivity有2個視圖:TextView和一個按鈕。點擊按鈕後,我正在運行一個AsyncTask,它進一步爲網絡操作創建10個新的AsyncTasks。每創建一項任務都會延遲1秒。代碼是:AsyncTask系列不會立即執行
public class MainActivity extends ActionBarActivity
{
TextView tv;
Button t;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
t = (Button) findViewById(R.id.toggleButton1);
t.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
getData();
}
});
}
void getData()
{
SuperNetworkAsyncTask s = new SuperNetworkAsyncTask();
s.execute("");
}
private class SuperNetworkAsyncTask extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... urls)
{
for(int i=0;i<10;i++)
{
{
nTask = new NetworkAsyncTask();
nTask.execute("");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return "";
}
@Override
protected void onPostExecute(String result)
{
}
}
private class NetworkAsyncTask extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... urls)
{
return String.valueOf(System.currentTimeMillis());
}
@Override
protected void onPostExecute(String result)
{
tv.setText(result);
}
}
}
我在期待那個時候第一次調用NetworkAsyncTask執行方法時,它會啓動執行。但是當我運行它時,我沒有發現任何NetworkAsyncTask開始執行,直到控件從SuperNetworkAsyncTask中出來。一旦調用execute方法,有沒有辦法推動NetworkAsyncTask線程的執行?
一些澄清:
爲什麼NetworkAsyncTask由SuperNetworkAsyncTask產生的?因爲如果我在主線程中創建NetworkAsyncTask,我的UI會凍結一段時間。
爲什麼要製作10個對象? NetworkAsyncTask的目的是以1秒的間隔從服務器讀取數據n秒,這裏n = 10。
第2部分:做一些測試後更新。
觀察: 作爲同胞布賴恩共享的方式,以避免嵌套的方式創造AsyncTasks,我想他的代碼:
void getData() {
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 10; i++) {
nTask = new NetworkAsyncTask();
nTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
}
這凍結我的UI幾秒鐘,然後屏幕在幾分之一秒內更新。我也很驚訝。
觀察:
隨着java.lang.Thread中,我嘗試以確保1)運行時調用()的線程應立即執行。 2)下一個任務只有在完成前一個任務後纔會創建。
代碼:
public static void main(String[] args) {
myThread m;
for (int i=0;i<10;i++)
{
m=new myThread(String.valueOf(i));
m.start();
synchronized (m)
{
try {
m.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class myThread extends Thread
{
public String name = "";
public myThread(String n)
{
name = n;
}
public void run()
{
synchronized (this)
{
System.out.println(" Thread Name = " + name);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
notifyAll();
}
}
}
輸出:
Thread Name = 0
Thread Name = 1
Thread Name = 2
Thread Name = 3
Thread Name = 4
Thread Name = 5
Thread Name = 6
Thread Name = 7
Thread Name = 8
Thread Name = 9
基於在此,我更新了我的NetworkAsyncTask & SuperNetworkAsyncTask爲:
private class NetworkAsyncTask extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... urls)
{
synchronized (this)
{
return String.valueOf(System.currentTimeMillis());
}
}
@Override
protected void onPostExecute(String result)
{
synchronized (this)
{
tv.setText(result);
notifyAll();
}
}
}
private class SuperNetworkAsyncTask extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... urls)
{
for(int i=0;i<10;i++)
{
nTask = new NetworkAsyncTask();
nTask.execute(url);
synchronized (nTask)
{
try {
nTask.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return "";
}
@Override
protected void onPostExecute(String result)
{
}
}
這段代碼的wait()的不斷無限期地等待。
最後我換成:
nTask.execute(url);
與
nTask.executeOnExecutor(THREAD_POOL_EXECUTOR, "");
這個工作以及預期。
從另一個AsyncTask啓動一系列AsyncTasks有什麼意義?你也可以從UI線程中完成。 – Egor
使用'executeOnExecutor'而不是'execute'。 [From Here](http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor,Params ...))。 – Marius
AsyncTask裏面的AsyncTask不是一個好的選擇。調用多線程執行並行或串行的順序取決於API版本。 'executeOnExecutor'可以處理同時運行的多個線程。 – Pr38y