我正在阅读有关的内容AsyncTask,并尝试了以下简单程序。但这似乎不起作用。我该如何运作?
public class AsyncTaskActivity extends Activity { Button btn; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) findViewById(R.id.button1); btn.setOnClickListener((OnClickListener) this); } public void onClick(View view){ new LongOperation().execute(""); } private class LongOperation extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { for(int i=0;i<5;i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } TextView txt = (TextView) findViewById(R.id.output); txt.setText("Executed"); return null; } @Override protected void onPostExecute(String result) { } @Override protected void onPreExecute() { } @Override protected void onProgressUpdate(Void... values) { } } }
我只是想在后台处理5秒后更改标签。
这是我的main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:indeterminate="false" android:max="10" android:padding="10dip"> </ProgressBar> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start Progress" > </Button> <TextView android:id="@+id/output" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Replace"/> </LinearLayout>
好的,您正在尝试通过另一个线程访问GUI。基本上,这不是一个好习惯。
AsyncTask在doInBackground()另一个线程内部执行所有操作,该线程无法访问您的视图所在的GUI。
AsyncTask
doInBackground()
preExecute()并postExecute()在此新线程发生繁重之前和之后为您提供访问GUI的权限,甚至可以将long操作的结果传递给postExecute(),然后显示任何处理结果。
preExecute()
postExecute()
请在以后更新TextView的地方查看这些行:
TextView txt = findViewById(R.id.output); txt.setText("Executed");
把它们放进去onPostExecute()。
onPostExecute()
doInBackground完成后,您将看到更新的TextView文本。
doInBackground
我注意到您的onClick侦听器不会检查是否已选择哪个视图。我发现最简单的方法是通过switch语句。我在下面编辑了一个完整的课程,其中包含所有建议,以免造成混淆。
import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.provider.Settings.System; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.view.View.OnClickListener; public class AsyncTaskActivity extends Activity implements OnClickListener { Button btn; AsyncTask<?, ?, ?> runningTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = findViewById(R.id.button1); // Because we implement OnClickListener, we only // have to pass "this" (much easier) btn.setOnClickListener(this); } @Override public void onClick(View view) { // Detect the view that was "clicked" switch (view.getId()) { case R.id.button1: if (runningTask != null) runningTask.cancel(true); runningTask = new LongOperation(); runningTask.execute(); break; } } @Override protected void onDestroy() { super.onDestroy(); // Cancel running task(s) to avoid memory leaks if (runningTask != null) runningTask.cancel(true); } private final class LongOperation extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... params) { for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { // We were cancelled; stop sleeping! } } return "Executed"; } @Override protected void onPostExecute(String result) { TextView txt = (TextView) findViewById(R.id.output); txt.setText("Executed"); // txt.setText(result); // You might want to change "executed" for the returned string // passed into onPostExecute(), but that is up to you } } }