kzen.dev
  • Spørsmål
  • Tagger
  • Brukere
Meldinger
Belønninger
Registrering
Når du har registrert deg, vil du bli varslet om svar og kommentarer til spørsmålene dine.
Logg inn
Hvis du allerede har en konto, kan du logge inn for å sjekke nye varsler.
Det vil være belønninger for spørsmål, svar og kommentarer.
Mer
Kilde
Rediger
 Fox
Fox
Spørsmål

AsyncTask Android-eksempel

Jeg leste om AsyncTask, og jeg prøvde det enkle programmet nedenfor. Men det ser ikke ut til å fungere. Hvordan kan jeg få det til å fungere?

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) {
        }
    }
}

Jeg prøver bare å endre etiketten etter 5 sekunder i bakgrunnsprosessen.

Dette er min 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 2012-03-12T17:09:39+00:00 6
Rohit Singh
Rohit Singh
Redigerte spørsmål 24. januar 2019 в 2:05
Programmering
android
android-asynctask
Dette spørsmålet har 1 svar på engelsk, for å lese dem logge inn på kontoen din.
 Suragch
Suragch
10. april 2015 в 10:41
2015-04-10T10:41:28+00:00
Mer
Kilde
Rediger
#15659053

Mitt fullstendige svar er her, men her er et forklarende bilde for å supplere de andre svarene på denne siden. For meg var det mest forvirrende i begynnelsen å forstå hvor alle variablene skulle.

Legg inn bildebeskrivelse her]2.

Valeriu
Valeriu 55958
Redigert svar 31. januar 2023 в 12:40
762
0
Løsning / svar
Graham Smith
Graham Smith
12. mars 2012 в 5:12
2012-03-12T17:12:49+00:00
Mer
Kilde
Rediger
#15659042

Ok, du prøver å få tilgang til brukergrensesnittet via en annen tråd. Dette er i hovedsak ikke god praksis.

AsyncTask utfører alt i doInBackground() inne i en annen tråd, som ikke har tilgang til GUI der visningene dine er.

preExecute() og postExecute() gir deg tilgang til GUI før og etter at det tunge løftet skjer i denne nye tråden, du kan til og med sende resultatet av den lange operasjonen til postExecute() for deretter å vise eventuelle resultater av behandlingen.

Se disse linjene der du senere oppdaterer TextView:

TextView txt = findViewById(R.id.output);
txt.setText("Executed");

legg dem i onPostExecute()

Du vil da se TextView-teksten oppdatert etter at doInBackground er fullført.

EDIT: Jeg la merke til at onClick-lytteren din ikke sjekker for å se hvilken visning som er valgt. Jeg finner den enkleste måten å gjøre dette på er via bytte uttalelser. Jeg har en komplett klasse redigert nedenfor med alle forslag for å spare forvirring.

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);
            // might want to change "executed" for the returned string passed
            // into onPostExecute() but that is upto you
        }
    }
}
 Miha_x64
Miha_x64
Redigert svar 11. oktober 2019 в 7:26
691
0
 bbedward
bbedward
12. mars 2012 в 5:15
2012-03-12T17:15:07+00:00
Mer
Kilde
Rediger
#15659043

Jeg er sikker på at den kjører riktig, men du prøver å endre brukergrensesnittelementene i bakgrunnstråden, og det vil ikke gjøre det.

Endre anropet og AsyncTask som følger:

Calling Class

Note: Jeg personlig foreslår at du bruker onPostExecute() uansett hvor du utfører AsyncTask-tråden din og ikke i klassen som utvider AsyncTask selv. Jeg tror det gjør koden lettere å lese, spesielt hvis du trenger AsyncTask på flere steder som håndterer resultatene litt annerledes.

new LongThread() {
    @Override public void onPostExecute(String result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}.execute("");

LongThread klassen (utvider AsyncTask):

@Override
protected String doInBackground(String... params) {
    for (int i = 0; i < 5; i++) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    return "Executed";
}      
Jared Burrows
Jared Burrows
Redigert svar 3. juni 2019 в 3:53
73
0
 nitesh
nitesh
16. september 2013 в 12:02
2013-09-16T12:02:21+00:00
Mer
Kilde
Rediger
#15659046

Konsept og kode her

Jeg har laget et enkelt eksempel for bruk av AsyncTask av Android. Det starter med onPreExecute(), doInBackground(), publishProgress() og til sluttonProgressUpdate().

I dette fungerer doInBackground() som en bakgrunnstråd, mens andre fungerer i UI-tråden. Du kan ikke få tilgang til et UI-element i doInBackground(). Sekvensen er den samme som jeg har nevnt.

Men hvis du trenger å oppdatere en widget fra doInBackground kan du publishProgress fra doInBackground som vil kalle onProgressUpdate for å oppdatere din UI widget.

class TestAsync extends AsyncTask<Void, Integer, String> {
    String TAG = getClass().getSimpleName();

    protected void onPreExecute() {
        super.onPreExecute();
        Log.d(TAG + " PreExceute","On pre Exceute......");
    }

    protected String doInBackground(Void...arg0) {
        Log.d(TAG + " DoINBackGround", "On doInBackground...");

        for (int i=0; i<10; i++){
            Integer in = new Integer(i);
            publishProgress(i);
        }
        return "You are at PostExecute";
    }

    protected void onProgressUpdate(Integer...a) {
        super.onProgressUpdate(a);
        Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d(TAG + " onPostExecute", "" + result);
    }
}

Kall den slik i aktiviteten din:

new TestAsync().execute();

Referanse for utviklere her

Valeriu
Valeriu 55958
Redigert svar 31. januar 2023 в 12:40
Jared Burrows
Jared Burrows
Redigert svar 3. juni 2019 в 3:54
58
0
Ted Hopp
Ted Hopp
12. mars 2012 в 5:16
2012-03-12T17:16:50+00:00
Mer
Kilde
Rediger
#15659044

Flytt disse to linjene:

TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");

ut av AsyncTask-metoden doInBackground og legg dem i onPostExecute-metoden. Din AsyncTask skal se omtrent slik ut:

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(5000); // no need for a loop
        } catch (InterruptedException e) {
            Log.e("LongOperation", "Interrupted", e);
            return "Interrupted";
        }
        return "Executed";
    }      

    @Override
    protected void onPostExecute(String result) {               
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}
16
0
Rohit Singh
Rohit Singh
25. januar 2019 в 6:20
2019-01-25T06:20:01+00:00
Mer
Kilde
Rediger
#15659058

Hvordan huske parametrene som brukes i AsyncTask?

Ikke gjør det

Hvis du er ny i AsyncTask, er det veldig vanlig å bli forvirret mens du skriver en AsyncTask. De viktigste synderne er parametrene som brukes i AsyncTask, dvs. AsyncTask<A,B,C>. Basert på A,B,C (argumenter) signaturen til metodene er forskjellig, noe som gjør ting enda mer forvirrende.

Hold det enkelt!

Nøkkelen er Ikke pugge. Hvis du kan visualisere hva oppgaven din virkelig trenger å gjøre, vil det være enkelt å skrive AsyncTask med riktig signatur ved første forsøk. Bare finn ut hva Input, Progress og Output er, så er du i gang.

Så hva er en AsyncTask?

AsyncTask er en bakgrunnsoppgave som kjører i bakgrunnstråden. Den tar en Input, utfører Progress og gir Output.

ie AsyncTask<input,Progress,output>.

For eksempel: skriv inn bildebeskrivelse her]1.

Hva er forholdet til metoder?

Mellom AsyncTask og doInBackground().

skriv inn bildebeskrivelse her]2

doInBackground() og onPostExecute(),onProgressUpdate()` er også relaterte

skriv inn bildebeskrivelse her].

Hvordan skriver jeg det i koden?

DownloadTask extends AsyncTask<String,Integer,String>{

  // Always same signature
  @Override
  public void onPreExecute()
  {}

  @Override
  public String doInbackGround(String... params)
  {
           // Download code
           int downloadPerc = // calculate that
           publish(downloadPerc);

           return "Download Success";
  }

  @Override
  public void onPostExecute(String result)
  {
      super.onPostExecute(result);
  }

  @Override
  public void onProgressUpdate(Integer... params)
  {
         // show in spinner, access UI elements
  }

}

}

DownloadTask extends AsyncTask<String,Integer,String>{

  // Always same signature
  @Override
  public void onPreExecute()
  {}

  @Override
  public String doInbackGround(String... params)
  {
           // Download code
           int downloadPerc = // calculate that
           publish(downloadPerc);

           return "Download Success";
  }

  @Override
  public void onPostExecute(String result)
  {
      super.onPostExecute(result);
  }

  @Override
  public void onProgressUpdate(Integer... params)
  {
         // show in spinner, access UI elements
  }

}

Hvordan vil du kjøre denne oppgaven?

new DownLoadTask().execute("Paradise.mp3");
new DownLoadTask().execute("Paradise.mp3");
Valeriu
Valeriu 55958
Redigert svar 31. januar 2023 в 12:40
7
0
Legg til spørsmål
Kategorier
Alle
Teknologi
Kultur / Fritid
Liv / Kunst
Vitenskap
Profesjonell
Virksomhet
Brukere
Alle
New
Popular
1
Ilya Smirnov
Registered 1 dag siden
2
Денис Васьков
Registered 2 dager siden
3
Dima Patrushev
Registered 4 dager siden
4
sirojidddin otaboyev
Registered 1 uke siden
5
Елена Гайдамамакинат
Registered 1 uke siden
CS
DE
EL
ES
ET
FR
ID
IT
JA
LT
NL
NO
PT
RO
RU
SK
TR
ZH
© kzen.dev 2023
Kilde
stackoverflow.com
under lisens cc by-sa 3.0 med attribusjon