初识安卓之:异步备份手机短信,详解自定义接口,回调抽象方法

主界面中的代码如下:


//本工程主要分析了异步备份手机里所有短信得到sd卡上时,工具类中的工具方法通过回调主函数中定义的抽象方法,向主函数实时传递自己备份了多少条短信
//从而在主函数可以显示进度条的动态效果,需要的权限:READ_SMS;WRITE_SMS;WRITE_EXTERNAL_STORAGE
//通过传递抽象对象的引用可以很好的解耦,使得工具方法只提供实时备份数据,主函数可以自由选择如何处理这些数据以便更好的呈现动态过程
public class MsgCopyToXMLActivity extends Activity {
    /** Called when the activity is first created. */
    private ProgressDialog pd;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    public void copyMsg(View view){
        try {
            File file = new File(Environment.getExternalStorageDirectory(),"smsbackup.xml");
            FileOutputStream fos = new FileOutputStream(file);
            //AsyncTask<执行异步任务时所必须的参数(如果必须的话),异步任务执行的进度,异步任务执行完毕后的返回值(就是backgroud方法的返回值类型)>——————>这里这三个值只能写数据类型,不能写具体对象
            new AsyncTask<OutputStream, Integer, Boolean>() {
                //后台执行的任务(所需参数的类型,可变参数数组(内含所需参数的值))
                @Override
                protected Boolean doInBackground(OutputStream... params) {
                    try {
                        MsgCopyUtil smsUtils = new MsgCopyUtil(getApplicationContext());
                        //params[0]=fos=execute所接受的参数
                        
                        //在后台任务中调用自定义的工具方法,该工具方法需要接受一个抽象类的对象(自己设计的抽象类)
                        /**
                         * 这里的第二个参数必须传一个自定义接口的对象,所以必须实现接口中的抽象方法才能创建出对象,相当于这里的这个对象是出生就
                         * 带着两个抽象方法的,把这个带着抽象方法的接口对象传给工具方法后,工具方法拿着传过来的这个接口对象想调用抽象方法,
                         * 就只能用我们创建接口对象时已经实现好的方法,也就是说,它是借用的我们的抽象方法去办事,它自己没有,因为它自己没实现
                         * 这个借用我们的抽象方法的过程就叫做:回调,这种抽象方法就叫做回调函数。
                         * 比如:listener.beforeBackup(cursor.getCount());这句话就是用了我们实现好的方法,而且给我们的方法传进去了一个参数
                         * 它回调时传的参数,我们这边可以立马捕获,因为它的对象本来就是我们的对象的引用
                         * 要始终记得:我们把自定义接口类型的对象(带着两个方法)传递给工具类的方法后,工具方法拿着这个自定义接口类型对象的引用调用抽象方法时,调用的不是工具类
                         * 中的抽象方法体,而是借用的我们已经实现了的抽象方法去做事,它用我们的方法办事,我们这边当然都可以拿到        
                         */
                        smsUtils.backUpSms(params[0],new MsgCopyUtil.BackUpProcessListener() {
                            
                            @Override
                            public void onProcessUpdate(int process) {
                                pd.setProgress(process);                                
                            }
                            
                            @Override
                            public void beforeBackup(int max) {
                                pd.setMax(max);                                
                            }
                        });
                        return true;
                    } catch (Exception e) {
                        e.printStackTrace();
                        return false;
                    }                    
                }
                //后台任务执行前的操作
                @Override
                protected void onPreExecute() {
                    pd = new ProgressDialog(MsgCopyToXMLActivity.this);
                    pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                    pd.setTitle("提示:");
                    pd.setMessage("正在备份短信....");
                    pd.show();
                    super.onPreExecute();
                }

                //后台任务执行后的操作
                @Override
                protected void onPostExecute(Boolean result) {
                    pd.dismiss();
                    if(result){
                        Toast.makeText(getApplicationContext(), "备份成功", 0).show();
                    }else{
                        Toast.makeText(getApplicationContext(), "备份失败", 0).show();
                    }
                    super.onPostExecute(result);
                }

                @Override
                protected void onProgressUpdate(Integer... values) {
                    // TODO Auto-generated method stub
                    super.onProgressUpdate(values);
                }                            
            }.execute(fos);
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(), "备份失败..", 1).show();
        }
        
        
    }
}


 

工具类代码如下

public class MsgCopyUtil {

    private Context context;

    public MsgCopyUtil(Context context) {
        this.context = context;
    }
    
    public interface BackUpProcessListener{
        void beforeBackup(int max);
        void onProcessUpdate(int process);
    }
    
    //后台执行的这个备份短信方法,除了接受一个输出流,还要提供一个接口,让调用者去选择自己想要的进度条样式,实现抽象方法,
    //这样,调用者一旦调用这些抽象方法,创建一个抽象对象后,由于抽象类是在这里定义的,new出来的对象引用指向这里的listener
    //相当于别处创建的对象通引用就遥控工具类的抽象对象了
    public void backUpSms(OutputStream os, BackUpProcessListener listener) throws Exception{
        Uri uri = Uri.parse("content://sms/");
        XmlSerializer  serializer = Xml.newSerializer();
        serializer.setOutput(os, "utf-8");
        serializer.startDocument("utf-8", true);
        serializer.startTag(null, "smss");
        Cursor cursor = context.getContentResolver().query(uri, new String[]{"address","date","type","body"} , null, null, null);
        //
        listener.beforeBackup(cursor.getCount());
        int total = 0;
        while(cursor.moveToNext()){
            String address = cursor.getString(0);
            String date  =cursor.getString(1);
            String type  =cursor.getString(2);
            String body  =cursor.getString(3);
            serializer.startTag(null, "sms");
            
            serializer.startTag(null, "address");
            serializer.text(address);
            serializer.endTag(null, "address");

            serializer.startTag(null, "date");
            serializer.text(date);
            serializer.endTag(null, "date");
            
            serializer.startTag(null, "type");
            serializer.text(type);
            serializer.endTag(null, "type");
            
            serializer.startTag(null, "body");
            serializer.text(body);
            serializer.endTag(null, "body");
            
            serializer.endTag(null, "sms");
            
            os.flush();
            total++;
            listener.onProcessUpdate(total);
            
        }
        cursor.close();
        serializer.endTag(null, "smss");
        serializer.endDocument();
        os.flush();
        os.close();
        
    }
    
    public void restoreSms(){
        //读取xml文件. 把每一条短信的数据获取出来,插入到系统的数据库
    }
    
}
原文地址:https://www.cnblogs.com/94007boy/p/2830457.html