fred-ye / summary

my blog
43 stars 9 forks source link

[Android]回调机制在Android项目中的应用 #18

Open fred-ye opened 10 years ago

fred-ye commented 10 years ago

Android项目中难免会涉及到一些比较耗时的操作,如从网络上取数据,读本地的文件等等。Android 也推荐我们去新开一个线程完成这些操作,而不要在主线程中执行。当这些操作完成之后再调用主线程去更新UI。很明显当....之后.....这种类型的逻辑便是一个回调的模式。本文以一个从网络上取数据的例子来解释如何应用回调机制来实现一种比较好的设计。

Android中对比较耗时的操作通常采用两种方式来实现,一种是利用Thread + Handler,新开一个Thread去处理操作,操作完成后,采用handler发送message,然后更新UI。另一种方式是采用AsyncTask来实现,在AsyncTask中的doInBackground方法中去完成耗时的操作,当然这个方法中的代码会运行在另一个线程中。操作完成后在onPostExecute方法中进行UI的更新操作。两种方式无好坏之分,但个人倾向于采用AsyncTask的实现方式,觉得更简洁清晰一些。

直接上代码:

public interface IFeedback {
    boolean onFeedback(String key, boolean isSuccess, Object object);
}
public class GetBookTask extends AsyncTask<String, Void, Object> {
    public static final String TAG = GetBookTask.class.getSimpleName();
    public static final String FEED_BACK_KEY = "GetBookTask";
    private IFeedback feedback;
    private boolean isSuccess = false; 
    public GetBookTask(IFeedback feedback) {
        this.feedback = feedback;
    }
    @Override
    protected Object doInBackground(String... params) {
        Log.i(TAG, "task executing....");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        isSuccess = true;
        return null;
    }
    protected void onPostExecute(Object result) {
        super.onPostExecute(result);
        feedback.onFeedback(FEED_BACK_KEY, this.isSuccess,
                result);
    }
}
    • GetFookTask
public class GetFoodTask extends AsyncTask<String, Void, Object>  {
    public static final String TAG = GetFoodTask.class.getSimpleName();
    public static final String FEED_BACK_KEY = "GetFoodTask";
    private IFeedback feedback;
    private boolean isSuccess = false;    
    public GetFoodTask(IFeedback feedback) {
        this.feedback = feedback;
    }
    @Override
    protected Object doInBackground(String... params) {
        Log.i(TAG, "task executing....");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        isSuccess = true;
        return null;
    }
    protected void onPostExecute(Object result) {
        super.onPostExecute(result);
        feedback.onFeedback(FEED_BACK_KEY, this.isSuccess,
                result);
    }
}
  • Activity
public class MainActivity extends Activity {
    public static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new GetBookTask(feedback).execute(new String[]{""});
        new GetFoodTask(feedback).execute(new String[]{""});
    }
    private final IFeedback feedback = new IFeedback(){
        @Override
        public boolean onFeedback(String key, boolean isSuccess, Object object) {
           if (GetBookTask.FEED_BACK_KEY.equals(key)) {
               if (isSuccess) {
                   Log.i(TAG, "GetBookTask execute success and update UI");
                   return true;
               }
           }
           if (GetFoodTask.FEED_BACK_KEY.equals(key)) {
               if(isSuccess) {
                   Log.i(TAG, "GetFoodTask execute success and update UI");
                   return true;
               }
           }
           return false;
        }       

    };    
}

总结一下

 new Thread() {
            @Override
            public void run() {
                try {
                    HttpResponse response = new DefaultHttpClient().execute(new HttpGet("http://www.baidu.com"));
                    //parse response
                    feedback.onFeedback(key, isSuccess, object);
                } catch (ClientProtocolException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }.start();