Android의 AsyncTask에서 값 반환
한 가지 간단한 질문입니다.다음에서 값을 반환할 수 있습니까?AsyncTask
?
//AsyncTask is a member class
private class MyTask extends AsyncTask<Void, Void, Void>{
protected Void doInBackground(Void... params) {
//do stuff
return null;
}
@Override
protected void onPostExecute(Void result) {
//do stuff
//how to return a value to the calling method?
}
}
그리고 내 안에서Activity
/Fragment
:
// The task is started from activity
myTask.execute()
// something like this?
myvalue = myTask.getvalue()
편집: Java에 익숙하지 않은 곳이 어디냐는 질문을 오래 전에 받았습니다.이제 Java에 익숙해졌으니 간단히 요약해 보겠습니다.
비동기 태스크의 포인트는 태스크가asynchronous
즉, 콜 후에execute()
태스크에서 태스크는 자체 스레드에서 실행되기 시작합니다. 원래 호출 스레드가 이미 다른 작업을 수행했기 때문에 비동기 태스크에서 값을 반환하는 것은 무의미합니다(태스크가 비동기 작업인 경우).
시간을 생각해 보세요.기본 스레드와 병렬로 실행되는 태스크를 시작했습니다.병렬 실행 작업이 완료되면 메인 스레드에서도 시간이 경과한 것입니다.병렬 태스크는 기본 스레드에 값을 반환하기 위해 과거로 돌아갈 수 없습니다.
저는 C에서 왔기 때문에 잘 몰랐습니다.하지만 많은 사람들이 같은 질문을 하고 있는 것 같아서 좀 더 명확히 해두려고 했어요.
그래서 하는 거야.UI 스레드에서 실행되며, 여기서 화면(또는 필요한 곳)으로 결과를 전달할 수 있습니다.최종 결과가 나올 때까지 호출되지 않습니다.중간 결과를 가져오려면 다음을 참조하십시오.
값을 처리하는 메서드를 호출하면 어떨까요?
public class MyClass extends Activity {
private class myTask extends AsyncTask<Void, Void, Void> {
//initiate vars
public myTask() {
super();
//my params here
}
protected Void doInBackground(Void... params) {
//do stuff
return null;
}
@Override
protected void onPostExecute(Void result) {
//do stuff
myMethod(myValue);
}
}
private myHandledValueType myMethod(Value myValue) {
//handle value
return myHandledValueType;
}
}
가장 쉬운 방법은 (필요에 따라 작성 시) 발신 객체를 비동기 태스크에 전달하는 것입니다.
public class AsyncGetUserImagesTask extends AsyncTask<Void, Void, Void> {
private MyImagesPagerFragment mimagesPagerFragment;
private ArrayList<ImageData> mImages = new ArrayList<ImageData>();
public AsyncGetUserImagesTask(MyImagesPagerFragment imagesPagerFragment) {
this.mimagesPagerFragment = imagesPagerFragment;
}
@Override
public Void doInBackground(Void... records) {
// do work here
return null;
}
@Override
protected void onPostExecute(Void result) {
mimagesPagerFragment.updateAdapter(mImages);
}
}
또한 콜링 클래스(액티비티 또는 프래그먼트)에서 다음 작업을 수행합니다.
public class MyImagesPagerFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
AsyncGetUserImagesTask mGetImagesTask = new AsyncGetUserImagesTask(this);
mGetImagesTask.execute();
}
그리고 온포스트ExecuteMethod는 원하는 원래 클래스의 메서드를 호출합니다.다음은 예를 제시하겠습니다.
public void updateAdapter(List<ImageData> images) {
mImageAdapter.setImages(images);
mImageAdapter.notifyDataSetChanged();
}
}
코드 예:액티비티는 AsyncTask를 사용하여 백그라운드스레드의 값을 취득한 후 AsyncTask는 processValue를 호출하여 결과를 Activity로 되돌립니다.
public class MyClass extends Activity {
private void getValue() {
new MyTask().execute();
}
void processValue(Value myValue) {
//handle value
//Update GUI, show toast, etc..
}
private class MyTask extends AsyncTask<Void, Void, Value> {
@Override
protected Value doInBackground(Void... params) {
//do stuff and return the value you want
return Value;
}
@Override
protected void onPostExecute(Value result) {
// Call activity method with results
processValue(result);
}
}
}
다음 것을 시도해 보십시오.myvalue = new myTask().execute().get();
- 비동기론이 종료되지 않을 때까지 프로세스를 정지합니다.
'프로토콜'을 사용하여 데이터를 위임 또는 제공해야 합니다.AsynTask
.
딜러와 데이터 소스
위임자는 프로그램에서 다른 개체가 이벤트를 만났을 때 해당 개체를 대신하거나 해당 개체와 함께 작업하는 개체입니다.(Apple 정의)
프로토콜은 일부 동작을 위임하는 방법을 정의하는 인터페이스입니다.
딜러: 백그라운드 스레드의 객체에서 이벤트를 캡처합니다.
비동기 태스크:
public final class TaskWithDelegate extends AsyncTask<..., ..., ...> {
//declare a delegate with type of protocol declared in this task
private TaskDelegate delegate;
//here is the task protocol to can delegate on other object
public interface TaskDelegate {
//define you method headers to override
void onTaskEndWithResult(int success);
void onTaskFinishGettingData(Data result);
}
@Override
protected Integer doInBackground(Object... params) {
//do something in background and get result
if (delegate != null) {
//return result to activity
delegate.onTaskFinishGettingData(result);
}
}
@Override
protected void onPostExecute(Integer result) {
if (delegate != null) {
//return success or fail to activity
delegate.onTaskEndWithResult(result);
}
}
}
액티비티:
public class DelegateActivity extends Activity implements TaskDelegate {
void callTask () {
TaskWithDelegate task = new TaskWithDelegate;
//set the delegate of the task as this activity
task.setDelegate(this);
}
//handle success or fail to show an alert...
@Override
void onTaskEndWithResult(int success) {
}
//handle data to show them in activity...
@Override
void onTaskFinishGettingData(Data result) {
}
}
편집: doInBackground에서 대리인을 호출하고 대리인이 일부 보기를 편집하려고 하면 메인 스레드에서만 보기를 조작할 수 있기 때문에 충돌합니다.
// this refers to Activity
this.runOnUiThread(new Runnable() {
@Override
public void run() {
// Here you can edit views when task notify some changes from background thread
textView.setText(someValue);
}
});
추가의
DATASOURCE: 백그라운드 스레드의 개체에 데이터 제공
비동기 태스크:
public final class TaskWithDataSource extends AsyncTask<..., ..., ...> {
//declare a datasource with type of protocol declared in this task
private TaskDataSource dataSource;
private Object data;
//here is the task protocol to can provide data from other object
public interface TaskDataSource {
//define you method headers to override
int indexOfObject(Object object);
Object objectAtIndex(int index);
}
@Override
protected void onPreExecute(Integer result) {
if (dataSource != null) {
//ask for some data
this.data = dataSource.objectAtIndex(0);
}
}
@Override
protected Integer doInBackground(Object... params) {
//do something in background and get result
int index;
if (dataSource != null) {
//ask for something more
index = dataSource.indexOfObject(this.data);
}
}
}
액티비티:
public class DataSourceActivity extends Activity implements TaskDataSource {
void callTask () {
TaskWithDataSource task = new TaskWithDataSource;
//set the datasource of the task as this activity
task.setDataSource(this);
}
//send some data to the async task when it is needed...
@Override
Object objectAtIndex(int index) {
return new Data(index);
}
//send more information...
@Override
int indexOfObject(Object object) {
return new object.getIndex();
}
}
범용 파라미터 사용
AsyncTask<Params, Progress, Result>
Params
유형: " " " "Progress
상황을 - "진행 상황"Result
유형: " " " "
라고 생각하다
Result = task(Params)
예
★★YourObject
" " " URL:
new AsyncTask<String, Void, YourObject>()
{
@Override
protected void onPreExecute()
{
/* Called before task execution; from UI thread, so you can access your widgets */
// Optionally do some stuff like showing progress bar
};
@Override
protected YourObject doInBackground(String... url)
{
/* Called from background thread, so you're NOT allowed to interact with UI */
// Perform heavy task to get YourObject by string
// Stay clear & functional, just convert input to output and return it
YourObject result = callTheServer(url);
return result;
}
@Override
protected void onPostExecute(YourObject result)
{
/* Called once task is done; from UI thread, so you can access your widgets */
// Process result as you like
}
}.execute("http://www.example.com/");
AsyncTask에서 결과를 얻으려면 다음 작업을 수행해야 합니다.super.onPostExcecute(result)
이는 백그라운드 및 비동기 태스크도 완료되었음을 의미하기 때문입니다.예를 들어 다음과 같습니다.
... into your async task
@Override
protected void onPostExecute(MyBeanResult result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (mWakeLock.isHeld()) {
mWakeLock.release();
}
super.onPostExecute(result);
MyClassName.this.checkResponseForIntent(result);
}
methodr checkResponseFor 및의도는 다음과 같습니다.
private void checkResponseForIntent(MyBeanResult response) {
if (response == null || response.fault != null) {
noServiceAvailable();
return;
}
... or do what ever you want, even call an other async task...
이 기능을 사용하는 데 문제가 있었습니다..get()
AsyncTask와 ProgressBar가 함께 사용할 수 없습니다.get()
doInBackground를 사용합니다.
도움이 되길 바랍니다.
MainActivity 클래스를 Async 클래스로 전달하면 내부 클래스의 MainActivity 함수에 액세스 할 수 있습니다.이 방법은 문제 없습니다.
public class MainActivity extends ActionBarActivity {
void callAsync()
{
Async as = new Async(this,12,"Test");
as.execute();
}
public void ReturnThreadResult(YourObject result)
{
// TO DO:
// print(result.toString());
}
}
public class Async extends AsyncTask<String, String, Boolean> {
MainActivity parent;
int param1;
String param2;
public Async(MainActivity parent,int param1,String param2){
this.parent = parent;
this.param1 = param1;
this.param2 = param2;
}
@Override
protected void onPreExecute(){};
@Override
protected YourObject doInBackground(String... url)
{
return result;
}
@Override
protected void onPostExecute(YourObject result)
{
// call an external function as a result
parent.ReturnThreadResult(result);
}
}
언급URL : https://stackoverflow.com/questions/9458258/return-a-value-from-asynctask-in-android
'itsource' 카테고리의 다른 글
Java에는 Integer, Float, Double, Long의 가변형이 있습니까? (0) | 2022.11.24 |
---|---|
Larabel Altural을 사용하여 마지막으로 삽입된 ID 가져오기 (0) | 2022.11.24 |
느린 SecureRandom 제너레이터에 대처하는 방법 (0) | 2022.11.24 |
인터페이스에는 스태틱메서드가 없지만 스태틱필드와 내부 클래스는 정상인 이유는 무엇입니까?[Java8 이전] (0) | 2022.11.24 |
ISO 8601 datetime 문자열을 Python datetime 개체로 변환하려면 어떻게 해야 합니까? (0) | 2022.11.24 |