zoukankan      html  css  js  c++  java
  • 初识安卓之:异步备份手机短信,详解自定义接口,回调抽象方法

    主界面中的代码如下:

    
    
    //本工程主要分析了异步备份手机里所有短信得到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文件. 把每一条短信的数据获取出来,插入到系统的数据库
        }
        
    }
  • 相关阅读:
    第一次作业
    第0次作业
    第14、15周作业
    第七周作业
    第六周作业
    第四周作业
    第三周作业
    第4次作业
    第3次作业
    第二次作业
  • 原文地址:https://www.cnblogs.com/94007boy/p/2830457.html
Copyright © 2011-2022 走看看