Meer
AsyncTask Android voorbeeld
Ik was aan het lezen over AsyncTask
, en ik probeerde het simpele programma hieronder. Maar het lijkt niet te werken. Hoe kan ik het laten werken?
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) {
}
}
}
Ik probeer alleen het label na 5 seconden in het achtergrondproces te veranderen.
Dit is mijn 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>
665
3
Ok, je probeert toegang te krijgen tot de GUI via een andere thread. Dit, in het algemeen, is geen goede praktijk.
De AsyncTask voert alles uit in
doInBackground()
in een andere thread, die geen toegang heeft tot de GUI waar je views zijn.preExecute()
enpostExecute()
bieden je toegang tot de GUI voor en na het zware werk in deze nieuwe thread, je kunt zelfs het resultaat van de lange operatie doorgeven aanpostExecute()
om vervolgens de resultaten van de verwerking te tonen.Zie deze regels waar je later je TextView aan het updaten bent:
zet ze in
onPostExecute()
Je zult dan zien dat je TextView tekst is bijgewerkt nadat de
doInBackground
is voltooid.EDIT: Het viel me op dat je onClick listener niet controleert welke View geselecteerd is. Ik vind de makkelijkste manier om dit te doen is via switch statements. Ik heb hieronder een complete class bewerkt met alle suggesties om verwarring te voorkomen.
Ik'weet zeker dat het goed wordt uitgevoerd, maar je'probeert de UI elementen in de achtergronddraad te veranderen en dat zal niet lukken.
Herzie je oproep en AsyncTask als volgt:
Aanroepende Klasse
Note: Ik stel persoonlijk voor om
onPostExecute()
te gebruiken waar je je AsyncTask thread ook uitvoert en niet in de class die AsyncTask zelf uitbreidt. Ik denk dat het de code makkelijker leesbaar maakt, vooral als je de AsyncTask op meerdere plaatsen nodig hebt en de resultaten iets anders afhandelt.LongThread klasse (breidt AsyncTask uit):
Verplaats deze twee lijnen:
uit je AsyncTask's
doInBackground
methode en zet ze in deonPostExecute
methode. JeAsyncTask
zou er ongeveer zo uit moeten zien: