AsyncTask가 별도의 클래스이기 때문에 OnPostExecute()의 결과를 주 활동으로 가져오는 방법은 무엇입니까?
저는 이 수업이 두 개 있습니다.입니다.AsyncTask
이제 나의 주요 활동에서 나는 결과를 얻을 필요가 있습니다.OnPostExecute()
에 시대에AsyncTask
기본 활동에 결과를 전달하거나 결과를 가져오는 방법은 무엇입니까?
여기 샘플 코드가 있습니다.
나의 주요 활동.
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
@Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
비동기 작업 클래스입니다.
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
@Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
쉬운:
를 작성
interface
서 클스, 치위String output
옵션이거나 반환할 변수일 수 있습니다.public interface AsyncResponse { void processFinish(String output); }
으로
AsyncTask
class, interface 클스이, 인페스선언을 합니다.AsyncResponse
syslog:public class MyAsyncTask extends AsyncTask<Void, Void, String> { public AsyncResponse delegate = null; @Override protected void onPostExecute(String result) { delegate.processFinish(result); } }
▁to다합니▁in▁need해▁activity▁you▁your당야신이 필요합니다.
implements
인이스AsyncResponse
.public class MainActivity implements AsyncResponse{ MyAsyncTask asyncTask =new MyAsyncTask(); @Override public void onCreate(Bundle savedInstanceState) { //this to set delegate/listener back to this class asyncTask.delegate = this; //execute the async task asyncTask.execute(); } //this override the implemented method from asyncTask @Override void processFinish(String output){ //Here you will receive the result fired from async class //of onPostExecute(result) method. } }
갱신하다
저는 이것이 여러분 중 많은 사람들이 좋아하는 것인지 몰랐습니다.여기 간단하고 편리한 사용 방법이 있습니다.interface
.
여전히 같은 것을 사용합니다.interface
참고로, 당신은 이것을 결합할 수 있습니다.AsyncTask
학생들
AsyncTask
래스클 :
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
// you may separate this or combined to caller class.
public interface AsyncResponse {
void processFinish(String output);
}
public AsyncResponse delegate = null;
public MyAsyncTask(AsyncResponse delegate){
this.delegate = delegate;
}
@Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
}
이 작업을 수행합니다.Activity
시간
public class MainActivity extends Activity {
MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){
@Override
void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
}
}).execute();
}
또는 활동에서 인터페이스를 다시 구현합니다.
public class MainActivity extends Activity
implements AsyncResponse{
@Override
public void onCreate(Bundle savedInstanceState) {
//execute the async task
new MyAsyncTask(this).execute();
}
//this override the implemented method from AsyncResponse
@Override
void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
}
}
두 해결책인 첫 와 세 해결책에서 , 은 방법을 .processFinish
다른 하나는 메서드가 호출자 매개 변수 안에 있다는 것입니다.세 번째는 중첩된 익명 클래스가 없기 때문에 더 깔끔합니다.
팁: 변경String output
,String response
,그리고.String result
서로 다른 개체를 가져오기 위해 서로 다른 일치 유형으로 이동합니다.
몇 가지 옵션이 있습니다.
둥지를 틀다
AsyncTask
의 안신계 .Activity
클래스. 여러 활동에서 같은 작업을 사용하지 않는다고 가정하면 이것이 가장 쉬운 방법입니다.모든 코드는 동일하게 유지되며, 기존 태스크 클래스를 활동 클래스 내에 중첩된 클래스로 이동합니다.public class MyActivity extends Activity { // existing Activity code ... private class MyAsyncTask extends AsyncTask<String, Void, String> { // existing AsyncTask code ... } }
지생성다니합를에 대한 정의 .
AsyncTask
은 당신의 ▁to▁your에 대한 참조입니다.Activity
여러분은 다과같은방작업인수스있할다습니화와 같은 할 수 .new MyAsyncTask(this).execute(param1, param2)
.public class MyAsyncTask extends AsyncTask<String, Void, String> { private Activity activity; public MyAsyncTask(Activity activity) { this.activity = activity; } // existing AsyncTask code ... }
이 코드는 기본 클래스에서 사용할 수 있습니다.그것은 나에게 효과가 있었지만, 나는 다른 방법으로 방법을 구현했습니다.
try {
String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get();
}
catch (ExecutionException | InterruptedException ei) {
ei.printStackTrace();
}
저는 아래의 접근법이 매우 쉽다고 느꼈습니다.
콜백을 위한 인터페이스를 선언했습니다.
public interface AsyncResponse {
void processFinish(Object output);
}
그런 다음 모든 유형의 병렬 요청에 응답하는 비동기 작업을 만들었습니다.
public class MyAsyncTask extends AsyncTask<Object, Object, Object> {
public AsyncResponse delegate = null;//Call back interface
public MyAsyncTask(AsyncResponse asyncResponse) {
delegate = asyncResponse;//Assigning call back interfacethrough constructor
}
@Override
protected Object doInBackground(Object... params) {
//My Background tasks are written here
return {resutl Object}
}
@Override
protected void onPostExecute(Object result) {
delegate.processFinish(result);
}
}
그런 다음 활동 클래스에서 단추를 클릭할 때 비동기 작업을 호출합니다.
public class MainActivity extends Activity{
@Override
public void onCreate(Bundle savedInstanceState) {
Button mbtnPress = (Button) findViewById(R.id.btnPress);
mbtnPress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {
@Override
public void processFinish(Object output) {
Log.d("Response From Asynchronous task:", (String) output);
mbtnPress.setText((String) output);
}
});
asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." });
}
});
}
}
감사해요.
이 답변이 늦을 수도 있지만 당신의 답변에 대해 몇 가지 언급하고 싶습니다.Activity
.AsyncTask
그러면 충돌을 방지하고 메모리를 관리하는 데 도움이 됩니다.위에서 이미 언급한 바와 같이 답변은 다음과 같습니다.interface
콜백이라고도 합니다.그들은 정보원으로 일할 것이지만 절대로 강한 언급을 보내지 않을 것입니다.Activity
또는interface
그런 경우에는 항상 약한 참조를 사용합니다.
그것이 어떻게 문제를 일으킬 수 있는지 아래 스크린샷을 참조하십시오.
가 시작했는지 , 우가시보다시피지는했작리.AsyncTask
강력한 언급과 함께, 그렇다면 우리의 것에 대한 보장은 없습니다.Activity
/Fragment
우리가 데이터를 얻을 때까지 살아있을 것이므로, 사용하는 것이 더 나을 것입니다.WeakReference
그런 경우에 그리고 그것은 또한 메모리 관리에 도움이 될 것입니다. 왜냐하면 우리는 결코 우리의 강력한 참조를 보유하지 않을 것이기 때문입니다.Activity
그러면 그것은 왜곡된 후 쓰레기 수거 대상이 될 것입니다.
아래 코드 스니펫을 확인하여 멋진 약한 참조를 사용하는 방법을 알아보십시오.
MyTaskInformer.java
정보 제공자 역할을 하는 인터페이스입니다.
public interface MyTaskInformer {
void onTaskDone(String output);
}
MySmallAsyncTask.java
긴 실행 작업을 수행하는 비동기 작업입니다. 이 작업은 다음을 사용합니다.WeakReference
.
public class MySmallAsyncTask extends AsyncTask<String, Void, String> {
// ***** Hold weak reference *****
private WeakReference<MyTaskInformer> mCallBack;
public MySmallAsyncTask(MyTaskInformer callback) {
this.mCallBack = new WeakReference<>(callback);
}
@Override
protected String doInBackground(String... params) {
// Here do whatever your task is like reading/writing file
// or read data from your server or any other heavy task
// Let us suppose here you get response, just return it
final String output = "Any out, mine is just demo output";
// Return it from here to post execute
return output;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// Here you can't guarantee that Activity/Fragment is alive who started this AsyncTask
// Make sure your caller is active
final MyTaskInformer callBack = mCallBack.get();
if(callBack != null) {
callBack.onTaskDone(s);
}
}
}
MainActivity.java
은 저의 이클스는나사용다니됩시작에의래▁my▁is를 시작할 때 합니다.AsyncTask
interface
이에서리그고업수고▁on그리.override
이 강제적인 방법
public class MainActivity extends Activity implements MyTaskInformer {
private TextView mMyTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMyTextView = (TextView) findViewById(R.id.tv_text_view);
// Start your AsyncTask and pass reference of MyTaskInformer in constructor
new MySmallAsyncTask(this).execute();
}
@Override
public void onTaskDone(String output) {
// Here you will receive output only if your Activity is alive.
// no need to add checks like if(!isFinishing())
mMyTextView.setText(output);
}
}
몇 줄로 할 수 있습니다. 포스트에서 재정의하십시오.비동기 작업을 호출할 때 실행합니다.다음은 당신을 위한 예입니다.
new AasyncTask()
{
@Override public void onPostExecute(String result)
{
// do whatever you want with result
}
}.execute(a.targetServer);
당신에게 도움이 되었기를 바랍니다, 행복한 커딩:)
Oncreate():
`
myTask.execute("url");
String result = "";
try {
result = myTask.get().toString();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}`
왜 사람들이 그렇게 힘들게 만드는 거지?
이 정도면 충분할 겁니다.
온포스트 구현 안 함비동기 작업을 실행하는 대신 활동에서 실행합니다.
public class MainActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState) {
//execute the async task
MyAsyncTask task = new MyAsyncTask(){
protected void onPostExecute(String result) {
//Do your thing
}
}
task.execute("Param");
}
}
의 방법을 호출할 수 있습니다.AsyncTask
(또는 오버로드됨).이 메서드는 다음 시간까지 차단됩니다.AsyncTask
작업이 완료되었으며, 그 시점에서 그것은 당신에게 반환할 것입니다.Result
.
비동기 작업의 생성/시작과 호출 사이에 다른 작업을 수행하는 것이 현명할 것입니다.get
방법, 그렇지 않으면 비동기 작업을 효율적으로 활용하지 못합니다.
청취자를 직접 작성할 수 있습니다.HelmiB의 답변과 동일하지만 더 자연스러워 보입니다.
수신기 인터페이스 만들기:
public interface myAsyncTaskCompletedListener {
void onMyAsynTaskCompleted(int responseCode, String result);
}
그런 다음 비동기 작업을 작성합니다.
public class myAsyncTask extends AsyncTask<String, Void, String> {
private myAsyncTaskCompletedListener listener;
private int responseCode = 0;
public myAsyncTask() {
}
public myAsyncTask(myAsyncTaskCompletedListener listener, int responseCode) {
this.listener = listener;
this.responseCode = responseCode;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
String result;
String param = (params.length == 0) ? null : params[0];
if (param != null) {
// Do some background jobs, like httprequest...
return result;
}
return null;
}
@Override
protected void onPostExecute(String finalResult) {
super.onPostExecute(finalResult);
if (!isCancelled()) {
if (listener != null) {
listener.onMyAsynTaskCompleted(responseCode, finalResult);
}
}
}
}
마지막으로 청취자를 활동에 구현합니다.
public class MainActivity extends AppCompatActivity implements myAsyncTaskCompletedListener {
@Override
public void onMyAsynTaskCompleted(int responseCode, String result) {
switch (responseCode) {
case TASK_CODE_ONE:
// Do something for CODE_ONE
break;
case TASK_CODE_TWO:
// Do something for CODE_TWO
break;
default:
// Show some error code
}
}
다음과 같이 asyncTask를 호출할 수 있습니다.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Some other codes...
new myAsyncTask(this,TASK_CODE_ONE).execute("Data for background job");
// And some another codes...
}
안녕하세요. 다음과 같은 것을 만들 수 있습니다.
AsyncTask를 구현하는 클래스 만들기
// TASK public class SomeClass extends AsyncTask<Void, Void, String>> { private OnTaskExecutionFinished _task_finished_event; public interface OnTaskExecutionFinished { public void OnTaskFihishedEvent(String Reslut); } public void setOnTaskFinishedEvent(OnTaskExecutionFinished _event) { if(_event != null) { this._task_finished_event = _event; } } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(Void... params) { // do your background task here ... return "Done!"; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if(this._task_finished_event != null) { this._task_finished_event.OnTaskFihishedEvent(result); } else { Log.d("SomeClass", "task_finished even is null"); } } }
기본 활동 추가
// MAIN ACTIVITY public class MyActivity extends ListActivity { ... SomeClass _some_class = new SomeClass(); _someclass.setOnTaskFinishedEvent(new _some_class.OnTaskExecutionFinished() { @Override public void OnTaskFihishedEvent(String result) { Toast.makeText(getApplicationContext(), "Phony thread finished: " + result, Toast.LENGTH_SHORT).show(); } }); _some_class.execute(); ... }
활동 클래스에 정적 구성원을 작성합니다.그런 다음 값을 지정합니다.onPostExecute
예를 들어 비동기 작업의 결과가 문자열인 경우 활동에 공용 정적 문자열을 만듭니다.
public static String dataFromAsyncTask;
에 러면에서onPostExecute
AsyncTask의 경우, 메인 클래스에 정적인 호출을 하고 값을 설정하기만 하면 됩니다.
MainActivity.dataFromAsyncTask = "result blah";
저는 스레드화와 핸들러/메시지를 사용하여 작동시킵니다.다음과 같은 단계:진행률 선언 대화 상자
ProgressDialog loadingdialog;
작업이 완료되면 대화 상자를 닫는 함수를 만듭니다.
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
loadingdialog.dismiss();
}
};
실행 세부 정보 코드화:
public void startUpload(String filepath) {
loadingdialog = ProgressDialog.show(MainActivity.this, "Uploading", "Uploading Please Wait", true);
final String _path = filepath;
new Thread() {
public void run() {
try {
UploadFile(_path, getHostName(), getPortNo());
handler.sendEmptyMessage(0);
} catch (Exception e) {
Log.e("threadmessage", e.getMessage());
}
}
}.start();
}
"프로토콜"을 사용하여 데이터를 위임하거나 데이터를 제공해야 합니다.AsynTask
.
딜러 및 데이터 소스
대리자는 프로그램에서 다른 개체가 이벤트를 만났을 때 해당 개체를 대신하거나 해당 개체와 조정하여 작동하는 개체입니다.(Apple 정의)
프로토콜은 일부 동작을 위임하는 몇 가지 방법을 정의하는 인터페이스입니다.
사용해 보십시오.
public class SomAsyncTask extends AsyncTask<String, Integer, JSONObject> {
private CallBack callBack;
public interface CallBack {
void async( JSONObject jsonResult );
void sync( JSONObject jsonResult );
void progress( Integer... status );
void cancel();
}
public SomAsyncTask(CallBack callBack) {
this.callBack = callBack;
}
@Override
protected JSONObject doInBackground(String... strings) {
JSONObject dataJson = null;
//TODO query, get some dataJson
if(this.callBack != null)
this.callBack.async( dataJson );// asynchronize with MAIN LOOP THREAD
return dataJson;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if(this.callBack != null)
this.callBack.progress(values);// synchronize with MAIN LOOP THREAD
}
@Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
if(this.callBack != null)
this.callBack.sync(jsonObject);// synchronize with MAIN LOOP THREAD
}
@Override
protected void onCancelled() {
super.onCancelled();
if(this.callBack != null)
this.callBack.cancel();
}
}
사용 예:
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Context _localContext = getContext();
SomeAsyncTask.CallBack someCallBack = new SomeAsyncTask.CallBack() {
@Override
public void async(JSONObject jsonResult) {//async thread
//some async process, e.g. send data to server...
}
@Override
public void sync(JSONObject jsonResult) {//sync thread
//get result...
//get some resource of Activity variable...
Resources resources = _localContext.getResources();
}
@Override
public void progress(Integer... status) {//sync thread
//e.g. change status progress bar...
}
@Override
public void cancel() {
}
};
new SomeAsyncTask( someCallBack )
.execute("someParams0", "someParams1", "someParams2");
}
아마도 조금 지나칠 수도 있지만 실행 코드와 결과 모두에 대한 콜백을 제공했습니다. 분명히 스레드 안전을 위해 실행 콜백에서 액세스하는 것에 주의해야 합니다.
비동기 작업 구현:
public class AsyncDbCall<ExecuteType,ResultType> extends AsyncTask<ExecuteType, Void,
ResultType>
{
public interface ExecuteCallback<E, R>
{
public R execute(E executeInput);
}
public interface PostExecuteCallback<R>
{
public void finish(R result);
}
private PostExecuteCallback<ResultType> _resultCallback = null;
private ExecuteCallback<ExecuteType,ResultType> _executeCallback = null;
AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback, PostExecuteCallback<ResultType> postExecuteCallback)
{
_resultCallback = postExecuteCallback;
_executeCallback = executeCallback;
}
AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback)
{
_executeCallback = executeCallback;
}
@Override
protected ResultType doInBackground(final ExecuteType... params)
{
return _executeCallback.execute(params[0]);
}
@Override
protected void onPostExecute(ResultType result)
{
if(_resultCallback != null)
_resultCallback.finish(result);
}
}
콜백:
AsyncDbCall.ExecuteCallback<Device, Device> updateDeviceCallback = new
AsyncDbCall.ExecuteCallback<Device, Device>()
{
@Override
public Device execute(Device device)
{
deviceDao.updateDevice(device);
return device;
}
};
마지막으로 비동기 작업을 실행합니다.
new AsyncDbCall<>(addDeviceCallback, resultCallback).execute(device);
당신이 이것을 겪었길 바랍니다, 그렇지 않다면 읽어주세요.
https://developer.android.com/reference/android/os/AsyncTask
결과 데이터의 특성에 따라 생각할 수 있는 최선의 옵션을 선택해야 합니다.
인터페이스를 사용하는 것은 좋은 선택입니다.
다른 선택지는..
AsyncTask 클래스가 결과를 사용할 클래스 내에 정의된 경우.정적 전역 변수를 사용하거나 get()를 사용하여 외부 클래스(필요한 경우 휘발성 변수)에서 사용합니다.그러나 비동기 작업 진행률을 알고 있거나 적어도 작업을 마쳤는지 확인해야 하며 글로벌 변수 / get() 메서드를 통해 결과를 사용할 수 있어야 합니다.폴링, ProgressUpdate(Progress...), 동기화 또는 인터페이스 중에서 가장 적합한 것을 사용할 수 있습니다.
결과가 공유 기본 설정 항목과 호환되거나 메모리에 파일로 저장해도 괜찮은 경우 백그라운드 작업 자체에서도 저장할 수 있으며 온포스트를 사용할 수 있습니다.Execute() 메서드
메모리에서 결과를 사용할 수 있을 때 알림을 받습니다.문자열이 충분히 작으며 활동을 시작할 때 사용해야 하는 경우.게시물 내에서 intent(추가() 입력)를 사용할 수 있습니다.실행(), 그러나 정적 컨텍스트는 안전하게 처리할 수 없습니다.
가능하면 온포스트에서 정적 메소드를 호출할 수 있습니다.execute() 메서드(결과를 매개 변수로 사용)
언급URL : https://stackoverflow.com/questions/12575068/how-to-get-the-result-of-onpostexecute-to-main-activity-because-asynctask-is-a
'programing' 카테고리의 다른 글
GIT: 특정 폴더로 체크아웃 (0) | 2023.08.30 |
---|---|
두 개의 제출 단추와 함께 jQuery agax 양식 제출 (0) | 2023.08.30 |
기록에 영향을 미치지 않고 해시 탐색을 사용할 수 있습니까? (0) | 2023.08.30 |
vba 버튼 - 클릭한 항목 찾기 (0) | 2023.08.30 |
RMariaDB 및 R의 풀을 사용하여 MariaDB로 전송된 여러 JSON 문자열 검사 (0) | 2023.08.30 |