简体   繁体   中英

AsyncTask data communication with nested Classes

I have a specific scenario and I need your help.

I'm trying to build an App in Android that involves network communication.

I am using AsyncTask for the http POST requests.
I have another class called Proxy (not a good one.. will be changed) which holds different kinds of functionalities (registerUser, setUserName, getUserPermission...)
And Of course, I have an Activity.

My Activity holds an instance of Proxy class. My goal, is to push a button in the activity, it will call a method from Proxy class, which in its turn calls the AsyncTask's execute() method that actually run the http POST.

I was wondering how to get the data from AsyncTask's onPostExecute to my activity.

What I have in mind is to have an interface in AsyncTask, which will be implemented in Proxy class, and another interface in Proxy class which will be implemented in my Activity class.

Roll the data all the way to my Activity.

I want to hear your thoughts about whether this is the way to go, or another approach is preffered.

Thanks a lot for your help.
Adding some code

public class RegisterActivity extends FragmentActivity implements Proxy.OnProxyHttpPostResponseListener {

private Proxy proxy;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        this.proxy = new Proxy();
        this.proxy.setHttpPostResponseListener(this);
    }

   @Override
   public void onProxyHttpPostResponse(String response) {
       //Do something when http post returns
   }
}


public class Proxy {

    public interface OnProxyHttpPostResponseListener {
        void onProxyHttpPostResponse(String response);
    }
    private OnProxyHttpPostResponseListener httpPostResponseListener;

    public void setHttpPostResponseListener(OnProxyHttpPostResponseListener listener) {
        this.httpPostResponseListener = listener;
    }


    private class HttpPostAsync extends AsyncTask<Pair<String, ArrayList<Pair<String, String>>>, Void, String> {

        @Override
        protected String doInBackground(Pair<String, ArrayList<Pair<String, String>>>... params) {
            return this.httpPost(params[0].first, params[0].second);
        }

        protected void onPostExecute(String response) {
            httpPostResponseListener.onProxyHttpPostResponse(response);
        }
    }

If you're just needing HTTP POST functionality then an AsyncTask might not be the best choice. AsyncTask really shines if you need to get progress updates as the task is executing (with onProgressUpdate(Progress... progress)). If you'd like to use AsyncTask nonetheless, iroiroys' reply should help.

A bit more simply, you could just use a Handler thread straight up. Something like this:

public class HandlerExampleActivity extends Activity {
    private Button postButton;
    private Button getButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler_example);

        backgroundThread = new BackgroundThread();
        backgroundThread.start();

        postButton = (Button) findViewById(R.id.button_post);
        postbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                backgroundThread.post("DATA_HERE");
            }
        });
        getButton = (Button) findViewById(R.id.button_get);
        getbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                backgroundThread.get("URL_HERE");
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        backgroundThread.exit();
    }

    private class BackgroundThread extends Thread {
        private Handler backgroundHandler;

        public void run() {
            Looper.prepare();
            backgroundHandler = new Handler();
            Looper.loop();
        }

        public void post(DataType data) {
            backgroundHandler.post(new Runnable() {
                @Override
                public void run() {
                    // pull data and do the POST

                    uiMsg = uiHandler.obtainMessage(POST_COMPLETE, whatever_data_passing_back, 0, null);
                    uiHandler.sendMessage(uiMsg);
                }
            });
        }

        public void get(URL data) {
            backgroundHandler.post(new Runnable() {
                @Override
                public void run() {
                    // GET data

                    uiMsg = uiHandler.obtainMessage(GET_COMPLETE, whatever_data_passing_back, 0, null);
                    uiHandler.sendMessage(uiMsg);
                }
            });
        }

        public void exit() {
            backgroundHandler.getLooper().quit();
        }
    }

    private final Handler uiHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case POST_COMPLETE:
                    // handle it
                    break;
                case GET_COMPLETE:
                    // handle it
                    break
                case MESSAGE_BACK_TO_UI_THREAD:
                    // do something
                    break;
                case OPERATION_FAIL:
                    // oh no!
                    break;
                case OPERATION_SUCCESS:
                    // yay!
                    break;
            }
        }
    };
}

I suggest you try Handler and Handler.Callback.

Below I made it simple example..

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;

public class MainActivity extends Activity implements Callback {

Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    handler = new Handler(this);
    Proxy proxy = new Proxy(handler);
    proxy.foo();
}

private class Proxy {

    Handler handler;

    public Proxy(Handler handler) {
        this.handler = handler;
    }

    private void foo() {
        new myAsync().execute();
    }

    private class myAsync extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Message msg = handler.obtainMessage();
            msg.obj = result;
            handler.sendMessage(msg);
        }

    }
}

@Override
public boolean handleMessage(Message msg) {
    // Handle Message here!
    return false;
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM