Convert android AsyncTask call to a separate class

2019-07-19 05:27发布

问题:

I am new to android development. I have a AsyncTask function in my application. Calling http request from all activities. Now in each activity I am using the following class to connect to server, in some activities I even called twice !!.

Basically I am a web developer and in such cases we use a single class which can be accessed from entire application(web) and use the common function to do the same activity. The only difference is input and out put will be changed.

My doubt is in this case can I use ( convert) this to such a function or class ? My assume is

  1. Create an android class ( which can be accessed from all the activities )
  2. Just make the JSON string we need with specific server ( for process in server )
  3. Just pass the created json to the created class and then made the http connect )
  4. Process the returned data from server
  5. Pass that to the corresponding activity

So that I can use the same function for all the activities and I can avoid duplicate query

Can I convert this code to such a manner ?

My Code

public class MainActivity extends Activity {




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_main);

                LogIN loginUser = new LogIN();
        LoginUser.execute("");


}

         private class LogIN extends AsyncTask<String, Integer, String> {


        @Override
        protected String doInBackground(String... sUrl) {
            try {


        String path = "http://www.domain_name.com/app/checkSession.php";

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); 

                HttpResponse response;
                JSONObject json = new JSONObject();
                try {
                    HttpPost post = new HttpPost(path);
                    json.put("access_token", "123456");


                    post.setHeader("json", json.toString());
                    StringEntity se = new StringEntity(json.toString());
                    se.setContentEncoding((Header) new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                    post.setEntity(se);

              response = client.execute(post);
                    /* Checking response */
                    if (response != null) {
                        InputStream in = response.getEntity().getContent(); 

                        String a = convertStreamToString(in);

                        JSONObject jsono = stringToJsonobj(a);
                        String passedStringValue = jsono.getString("result");

                        if(passedStringValue.equals("1")){
                            flags=1;
                            //Log.v("TAGG", "Success");
                        }
                        else {
                            flags=0;
                            //Log.v("TAGG", "Failed !");
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }








            } catch (Exception e) {
            }
            return null;
        }

        @Override
        protected void onPreExecute() {


            super.onPreExecute();
            showDialogue("Login Processing", "Loading");
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
        }

        @Override
        protected void onPostExecute(String result) {
            if(flags.equals(1)){
            Itent homepage = new Intent(MainActivity.this, RegisterDevice.class);
            startActivity(homepage);
            finish();
            }
            else {
                Intent homepage = new Intent(MainActivity.this, LoginActivity.class);
                startActivity(homepage);
                finish();
            }
            super.onPostExecute(result);
        }

    }

}

Please any one help/advise Thanks in advance

回答1:

Extract your class to a different file and make it public

    public class LogIN extends AsyncTask<Object, Integer, String> {
        private ILoginListener listener;

        @Override
        protected String doInBackground(Object... arg0) {
            try {
               this.listener = (ILoginListener) arg0[0];
              //You can also send the url in the obj array
              String theUrl = (String) arg0[1];


        String path = "http://www.domain_name.com/app/checkSession.php";

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); 

                HttpResponse response;
                JSONObject json = new JSONObject();
                try {
                    HttpPost post = new HttpPost(path);
                    json.put("access_token", "123456");


                    post.setHeader("json", json.toString());
                    StringEntity se = new StringEntity(json.toString());
                    se.setContentEncoding((Header) new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                    post.setEntity(se);

              response = client.execute(post);
                    /* Checking response */
                    if (response != null) {
                        InputStream in = response.getEntity().getContent(); 

                        String a = convertStreamToString(in);

                        JSONObject jsono = stringToJsonobj(a);
                        String passedStringValue = jsono.getString("result");

                        if(passedStringValue.equals("1")){
                            flags=1;
                            //Log.v("TAGG", "Success");
                        }
                        else {
                            flags=0;
                            //Log.v("TAGG", "Failed !");
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }








            } catch (Exception e) {
            }
            return null;
        }

        @Override
        protected void onPreExecute() {


            super.onPreExecute();
            showDialogue("Login Processing", "Loading");
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
        }

        @Override
        protected void onPostExecute(String result) {
            listener.logInSessionCheckListener(flag.equals(1));
            super.onPostExecute(result);
        }

    }

Regarding your other question, I normally have an interface for that, something like this:

    public interface ILoginListener {

        public void logInSessionCheckListener(SomeNeeded Value);

     }

I implement the interface in the class where i need the postExecute result and in the overriden method you can to what you want with the result of your task. Your class where you user it will look something like this:

public class SomeClass implements ILoginListener { 

    //Call it like this from any class:

    LogIN loginTask = new LogIn();

    Object[] someParams = new Object[2]; 
    //add the listener
    someParams[0] = SomeClass.this
    //add the url 
    someParams[1] = someUrlString;

    loginTask.execute(someParams);

   @Override
   public void logInSessionCheckListener(SomeNeeded Value){
    //do Stuff with your results

   }
}


回答2:

You can do it like make separate class for everything inside doInBackground() method and called it in all activity with passing parameter to

   LogIN loginUser = new LogIN(yourparameter);
    LoginUser.execute("");

and check parameter in AsyncTask Class constructor like

 public LogIN(Myparameter){
        // Your data
      }


回答3:

On the other hand you can use this great framework for android : android-query and the async API. It allows you to perform asynchroneous network tasks from activities and easily work with the results of your requests.



回答4:

You should use interfaces to implement a callback to your ui activity. Have a look at this thread, it might be useful: android asynctask sending callbacks to ui And your asyntask class should be in a seperate java file with public acces.

And to pass the parametres you simply have to call a new LogIN async Task like this:

new LogIN().execute(urls);

Hope it helped :)



回答5:

Remember that you can never know when AsyncTask is going to finish. So if you're using this to authenticate users and then perform task X, task Y, or task Z,

then maybe it's better to create a Login helper class

public class LoginHelper {

public boolean login(params){
    // Authenticate user and return true if successfull
}

}

and then have in your Activity classes

private class X extends AsyncTask {

@Override
protected String doInBackground(String... sUrl) {

    ...
    boolean authenticated = LoginHelper.login(params...);

    if(authenticated == true) {
        // Perform task X here...
    } else {
        // Inform the user that the login failed...
    }

}



回答6:

First of all You have to pass the context in which you are calling your async task

Sample Code

Login loginTask = new Long(getContext());
loginTask.execute();

You class Login should have a constructor that accepts the Context

Sample Code

public class Login extends AsyncTask<String, Integer, String> {

private Context mContext ;
private ProgressDialog pd; 
private Handler handler = new Handler { };
public Login (Context context){
mContext = context ;
}
.....

Then make sure to create the method showDialog inside Login class to show the progress dialog

Note You can add what ever Constructors you need to customize the behaviour of your Login task for example : pass boolean parameter to tell that the Login Task is cancelable....

Hope that help you :)