AsyncTask Android - Design Pattern and Return Values

后端 未结 2 405
忘了有多久
忘了有多久 2020-12-07 23:15

I\'m writing an application that validates login credentials on an external webserver - so I have the basic issue of creating a login screen that when submitted will send an

2条回答
  •  伪装坚强ぢ
    2020-12-07 23:52

    suppose the data format with web api is json, my design pattern :

    common classes
    1.MyAsyncTask : extends AsyncTask
    2.BackgroundBase : parameters to server
    3.API_Base : parameters from server
    4.MyTaskCompleted : callback interface

    public class MyAsyncTask extends AsyncTask {
        private ProgressDialog pd ; 
        private MyTaskCompleted listener;
        private Context cxt;
        private Class resultType;
        private String url;
        private int requestCode;    
    
        public MyAsyncTask(MyTaskCompleted listener, Class resultType, int requestCode, String url){
            this.listener = listener;
            this.cxt = (Context)listener;
            this.requestCode = requestCode;
            this.resultType = resultType;
            this.url = url;
        }
        public MyAsyncTask(MyTaskCompleted listener, Class resultType, int requestCode, String url, ProgressDialog pd){
                this(listener, resultType, requestCode, url);
                this.pd = pd;
                this.pd.show();
        }   
    
        @Override
        protected APIClass doInBackground(BackgroundClass... params) {
            APIClass result = null;
            try {           
                //do something with url and params, and get data from WebServer api
                BackgroundClass oParams = params[0];
                String sUrl = url + "?d=" + URLEncoder.encode(oParams.getJSON(), "UTF-8");
                String source = "{\"RtnCode\":1, \"ResultA\":\"result aaa\", \"ResultB\":\"result bbb\"}";
    
                //to see progressdialog
                Thread.sleep(2000);
    
                result = new com.google.gson.Gson().fromJson(source, resultType);           
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return result;
        }
    
         @Override
         protected void onPostExecute(APIClass result) {
            super.onPostExecute(result);
    
            try {
                if(pd != null && pd.isShowing())
                    pd.dismiss();
    
                API_Base oApi_Base = (API_Base)result;          
                listener.onMyTaskCompleted(result , this.requestCode);                      
            } catch (Exception e) {
                e.printStackTrace();
            }           
        }
    
    }
    public class API_Base {
        public int RtnCode;
    
        public String getJSON(Context context) throws Exception
        {
            return new com.google.gson.Gson().toJson(this);
        }
    
    
        public String toString(){
            StringBuilder sb = new StringBuilder();
    
            for (Field field : this.getClass().getFields()) {
                try {
                    field.setAccessible(true); 
                    Object value = field.get(this); 
                    if (value != null) {
                        sb.append(String.format("%s = %s\n", field.getName(), value));
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
    
            }
    
            return sb.toString();
        }
    
    }
    public class BackgroundBase {
    
        public String getJSON() throws Exception
        {       
            return new com.google.gson.Gson().toJson(this);
        }
    
    }
    public interface MyTaskCompleted {
        void onMyTaskCompleted(API_Base oApi_Base, int requestCode) ;
    }
    


    example, let's call two api in one activity
    assume :
    API 1.http://www.google.com/action/a
    input params : ActionA
    output params : RtnCode, ResultA

    API 2.http://www.google.com/action/b
    input params : ActionB
    output params : RtnCode, ResultB

    classes with example :
    1.MyActivity : extends Activity and implements MyTaskCompleted
    2.MyConfig : utility class, i set requestCode here
    3.BackgroundActionA, BackgroundActionB : model classes for api's input params
    4.API_ActionA, API_ActionB : model classes for api's output params

    public class MyActivity extends Activity implements MyTaskCompleted {
        ProgressDialog pd;
        Button btnActionA, btnActionB;
        TextView txtResult;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setContentView(R.layout.my_layout);
            btnActionA = (Button)findViewById(R.id.btn_actionA);
            btnActionB = (Button)findViewById(R.id.btn_actionB);
            txtResult = (TextView)findViewById(R.id.txt_result);
    
            btnActionA.setOnClickListener(listener_ActionA);
            btnActionB.setOnClickListener(listener_ActionB);
    
            pd = new ProgressDialog(MyActivity.this);
            pd.setTitle("Title");
            pd.setMessage("Loading");
        }
    
        Button.OnClickListener listener_ActionA = new Button.OnClickListener(){
    
            @Override
            public void onClick(View v) {
                //without ProgressDialog
                BackgroundActionA oBackgroundActionA = new BackgroundActionA("AAA");
                new MyAsyncTask(MyActivity.this, 
                                                                API_ActionA.class, 
                                                                MyConfig.RequestCode_actionA,
                                                                "http://www.google.com/action/a").execute(oBackgroundActionA);
            }
    
        };
        Button.OnClickListener listener_ActionB = new Button.OnClickListener(){
    
            @Override
            public void onClick(View v) {
                //has ProgressDialog
                BackgroundActionB oBackgroundActionB = new BackgroundActionB("BBB");
                new MyAsyncTask(MyActivity.this, 
                                                                API_ActionB.class, 
                                                                MyConfig.RequestCode_actionB,
                                                                "http://www.google.com/action/b",
                                                                MyActivity.this.pd).execute(oBackgroundActionB);
            }
    
        };
    
        @Override
        public void onMyTaskCompleted(API_Base oApi_Base, int requestCode) {
            // TODO Auto-generated method stub
            if(requestCode == MyConfig.RequestCode_actionA){
                API_ActionA oAPI_ActionA = (API_ActionA)oApi_Base;
                txtResult.setText(oAPI_ActionA.toString());
    
            }else if(requestCode == MyConfig.RequestCode_actionB){
                API_ActionB oAPI_ActionB = (API_ActionB)oApi_Base;
                txtResult.setText(oAPI_ActionB.toString());
    
            }
    
        }
    
    }
    public class MyConfig {
        public static String LogTag = "henrytest";
    
        public static int RequestCode_actionA = 1001;
        public static int RequestCode_actionB = 1002;
    }
    public class BackgroundActionA extends BackgroundBase {
        public String ActionA ;
    
        public BackgroundActionA(String actionA){
            this.ActionA = actionA;
        }
    
    }
    public class BackgroundActionB extends BackgroundBase {
        public String ActionB;
    
        public BackgroundActionB(String actionB){
            this.ActionB = actionB;
        }
    }
    public class API_ActionA extends API_Base {
        public String ResultA;
    }
    public class API_ActionB extends API_Base {
        public String ResultB;
    }
    


    Advantage with this design pattern :
    1.one Advantage for multi api
    2.just add model classes for new api, ex: BackgroundActionA and API_ActionA
    3.determine which API by different requestCode in callback function : onMyTaskCompleted

提交回复
热议问题