源码阅读--xutil3

2019-02-21 14:57:58 浏览数 (1)

初始化:

代码语言:javascript复制
public static void init(Application app) {
            TaskControllerImpl.registerInstance();
            if (Ext.app == null) {
                Ext.app = app;//-----------将Application绑定到app上,方便全局调用
            }
        }

1.view的绑定

代码语言:javascript复制
public interface ViewInjector {
    /**
     * 注入view
     */
    void inject(View view);

    /**
     * 注入activity
     */
    void inject(Activity activity);

    /**
     * 注入view holder
     */
    void inject(Object handler, View view);

    /**
     * 注入fragment
     */
    View inject(Object fragment, LayoutInflater inflater, ViewGroup container);
}

我们就来看看“注入activity”部分

代码语言:javascript复制
    @Override
    public void inject(Activity activity) {
        //-----------------------------------------------------------获取Activity的ContentView的注解
        Class<?> handlerType = activity.getClass();
        try {
            ContentView contentView = findContentView(handlerType);
            if (contentView != null) {
                int viewId = contentView.value();
                if (viewId > 0) {
                    //------------------------------------------------------------------找到setContentView方法
                    Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);
                    setContentViewMethod.invoke(activity, viewId);
                }
            }
        } catch (Throwable ex) {
            LogUtil.e(ex.getMessage(), ex);
        }

        injectObject(activity, handlerType, new ViewFinder(activity));
    }

    private static void injectObject(Object handler, Class<?> handlerType, ViewFinder finder) {
        // 从父类到子类递归
        injectObject(handler, handlerType.getSuperclass(), finder);

        // inject view
        Field[] fields = handlerType.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {

                Class<?> fieldType = field.getType();
                if (
                /* 不注入静态字段 */     Modifier.isStatic(field.getModifiers()) ||
                /* 不注入final字段 */    Modifier.isFinal(field.getModifiers()) ||
                /* 不注入基本类型字段 */  fieldType.isPrimitive() ||
                /* 不注入数组类型字段 */  fieldType.isArray()) {
                    continue;
                }

                ViewInject viewInject = field.getAnnotation(ViewInject.class);
                if (viewInject != null) {
                    try {
                        View view = finder.findViewById(viewInject.value(), viewInject.parentId());
                        if (view != null) {
                            field.setAccessible(true);
                            field.set(handler, view);
                        } else {
                            throw new RuntimeException("Invalid @ViewInject for "
                                      handlerType.getSimpleName()   "."   field.getName());
                        }
                    } catch (Throwable ex) {
                        LogUtil.e(ex.getMessage(), ex);
                    }
                }
            }
        } // end inject view

        // inject event
        Method[] methods = handlerType.getDeclaredMethods();
        if (methods != null && methods.length > 0) {
            for (Method method : methods) {
                //检查当前方法是否是event注解的方法
                Event event = method.getAnnotation(Event.class);
                if (event != null) {
                    try {
                        // id参数
                        int[] values = event.value();
                        int[] parentIds = event.parentId();
                        int parentIdsLen = parentIds == null ? 0 : parentIds.length;
                        //循环所有id,生成ViewInfo并添加代理反射
                        for (int i = 0; i < values.length; i  ) {
                            int value = values[i];
                            if (value > 0) {
                                ViewInfo info = new ViewInfo();
                                info.value = value;
                                info.parentId = parentIdsLen > i ? parentIds[i] : 0;
                                method.setAccessible(true);
                                EventListenerManager.addEventMethod(finder, info, event, handler, method);
                            }
                        }
                    } catch (Throwable ex) {
                        LogUtil.e(ex.getMessage(), ex);
                    }
                }
            }
        } // end inject event

    }

2.数据库访问

使用

代码语言:javascript复制
DbManager.DaoConfig daoConfig = new DbManager.DaoConfig();//----------------默认db名字:xUtils.db
        DbManager db = x.getDb(daoConfig);//-----------------------获取DbManagerImpl并且判断是否需要更新数据库
        Child child1 = new Child();
        child1.setName("111");
        Child child2 = new Child();
        child2.setName("222");
        try {
            db.save(child1);//-----------------------------------在后面
            db.save(child2);
        } catch (DbException e) {
            e.printStackTrace();
        }

        try {
            List<Child> childs = db.selector(Child.class).findAll();//----------------------------------在后面
            for (int i = 0; i < childs.size(); i  ) {
                Log.e("----", "child"   i   ".name="   childs.get(i).getName());
            }
        } catch (DbException e) {
            e.printStackTrace();
        }
代码语言:javascript复制
    public void save(Object entity) throws DbException {
        try {
            beginTransaction();//--------------------------事务

            if (entity instanceof List) {
                List<?> entities = (List<?>) entity;
                if (entities.isEmpty()) return;
                TableEntity<?> table = this.getTable(entities.get(0).getClass());
                createTableIfNotExist(table);
                for (Object item : entities) {
                    execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, item));
                }
            } else {
                TableEntity<?> table = this.getTable(entity.getClass());
                createTableIfNotExist(table);//--------------------------生成表
                //---------------------最重要的两句SqlInfoBuilder.buildCreateTableSqlInfo(生成表)和execNonQuery(执行sql语句来生成表)
                execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity));//------------------生成insert语句并且执行
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }

    public List<T> findAll() throws DbException {
        if (!table.tableIsExist()) return null;

        List<T> result = null;
        Cursor cursor = table.getDb().execQuery(this.toString());//---------------------------获取Cursor
        if (cursor != null) {
            try {
                result = new ArrayList<T>();
                while (cursor.moveToNext()) {//---------------------------------------------移动Cursor获取数据
                    T entity = CursorUtils.getEntity(table, cursor);
                    result.add(entity);
                }
            } catch (Throwable e) {
                throw new DbException(e);
            } finally {
                IOUtil.closeQuietly(cursor);
            }
        }
        return result;
    }

3.加载图片

代码语言:javascript复制
    public void bind(final ImageView view, final String url) {
        x.task().autoPost(new Runnable() {
            @Override
            public void run() {
                ImageLoader.doBind(view, url, null, null);
            }
        });
    }

    //--------------------------出现了Looper,明显异步线程
    @Override
    public void autoPost(Runnable runnable) {
        if (runnable == null) return;
        if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
            runnable.run();
        } else {
            TaskProxy.sHandler.post(runnable);
        }
    }

    //--------------------------内存缓存有就直接用,没有就ImageLoader().doLoad
    static Cancelable doBind(final ImageView view, final String url,
                             final ImageOptions options, final Callback.CommonCallback<Drawable> callback) {

        ......

        // load from Memory Cache
        Drawable memDrawable = null;
        if (localOptions.isUseMemCache()) {
            memDrawable = MEM_CACHE.get(key);//-------------------------------------MEM_CACHE是内存缓存
            if (memDrawable instanceof BitmapDrawable) {
                Bitmap bitmap = ((BitmapDrawable) memDrawable).getBitmap();
                if (bitmap == null || bitmap.isRecycled()) {
                    memDrawable = null;
                }
            }
        }
        if (memDrawable != null) { // has mem cache
            boolean trustMemCache = false;
            try {
                if (callback instanceof ProgressCallback) {
                    ((ProgressCallback) callback).onWaiting();
                }
                // hit mem cache
                view.setScaleType(localOptions.getImageScaleType());
                view.setImageDrawable(memDrawable);
                trustMemCache = true;
                if (callback instanceof CacheCallback) {
                    trustMemCache = ((CacheCallback<Drawable>) callback).onCache(memDrawable);
                    if (!trustMemCache) {
                        // not trust the cache
                        // load from Network or DiskCache
                        return new ImageLoader().doLoad(view, url, localOptions, callback);
                    }
                } else if (callback != null) {
                    callback.onSuccess(memDrawable);
                }
            } 
        } else {
            // load from Network or DiskCache
            return new ImageLoader().doLoad(view, url, localOptions, callback);
        }
        return null;
    }

    //---------------------------------从网络中获取(createRequestParams里面有diskcache的设置)
    private Cancelable doLoad(ImageView view, String url,
                              ImageOptions options, Callback.CommonCallback<Drawable> callback) {

        ......

        // request-----------------------------------------------------下面就是从网络中获取
        RequestParams params = createRequestParams(url, options);
        if (view instanceof FakeImageView) {
            synchronized (FAKE_IMG_MAP) {
                FAKE_IMG_MAP.put(url, (FakeImageView) view);
            }
        }
        return cancelable = x.http().get(params, this);
    }

4.网络访问

最简单的get请求

代码语言:javascript复制
        String url = "http://app.manpianyi.com/api/mpy/v3/global.php?"  
                "&pwd=de8cd30f8dec18fef502cdb9a584f512&version=2.4.1";
        RequestParams argPar = new RequestParams(url);

        x.http().request(HttpMethod.GET, argPar, new Callback.CommonCallback<String>() {
            ......
        });

request源码:

代码语言:javascript复制
        HttpTask<T> task = new HttpTask<T>(entity, cancelable, callback);
        return x.task().start(task);

    public <T> AbsTask<T> start(AbsTask<T> task) {
        TaskProxy<T> proxy = null;
        ......
        try {
            proxy.doBackground();//-------------------------------------------------
        } catch (Throwable ex) {
            LogUtil.e(ex.getMessage(), ex);
        }
        return proxy;
    }

    protected final ResultType doBackground() throws Throwable {
        PriorityRunnable runnable = new PriorityRunnable(
                task.getPriority(),
                new Runnable() {
                    @Override
                    public void run() {
                            ......

                            // start running
                            TaskProxy.this.onStarted();

                            ......

                            // 执行task, 得到结果.
                            task.setResult(task.doBackground());///---------------------------------------------
                            TaskProxy.this.setResult(task.getResult());

                            ......

                            // 执行成功
                            TaskProxy.this.onSuccess(task.getResult());
                    }
                });
        this.executor.execute(runnable);
        return null;
    }


    protected ResultType doBackground() throws Throwable {

        ......

        // 检查缓存
        Object cacheResult = null;
        if (cacheCallback != null && HttpMethod.permitsCache(params.getMethod())) {
            // 尝试从缓存获取结果, 并为请求头加入缓存控制参数.
            try {
                clearRawResult();
                LogUtil.d("load cache: "   this.request.getRequestUri());
                rawResult = this.request.loadResultFromCache();//--------------------------------------------------
            } catch (Throwable ex) {
                LogUtil.w("load disk cache error", ex);
            }
            ......
        }

        // 发起请求
        retry = true;
        while (retry) {
            retry = false;
            try {
                // 由loader发起请求, 拿到结果.
                this.request.close(); // retry 前关闭上次请求

                try {
                    clearRawResult();
                    // 开始请求工作
                    LogUtil.d("load: "   this.request.getRequestUri());
                    requestWorker = new RequestWorker();
                    requestWorker.request();//----------------------------------------调用request.loadResult(假设下载的是文件,那就是FileLoader.load)
                    if (requestWorker.ex != null) {
                        throw requestWorker.ex;
                    }
                    rawResult = requestWorker.result;
                } catch (Throwable ex) {
                    ......
                }

                ......

                // -------------------------------------------------------保存缓存
                if (cacheCallback != null && HttpMethod.permitsCache(params.getMethod())) {
                    this.request.save2Cache();
                }
            } catch (HttpRedirectException redirectEx) {
                retry = true;
                LogUtil.w("Http Redirect:"   params.getUri());
            } catch (Throwable ex) {
                ......
            }

        }

        return result;
    }

    //------------------------------------------------------------
    public File load(final InputStream in) throws Throwable {
        File targetFile = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            targetFile = new File(tempSaveFilePath);

            ......下载前的准备工作

            // 开始下载
            long current = 0;
            FileOutputStream fileOutputStream = null;
            if (isAutoResume) {
                current = targetFileLen;
                fileOutputStream = new FileOutputStream(targetFile, true);
            } else {
                fileOutputStream = new FileOutputStream(targetFile);
            }

            long total = contentLength   current;
            bis = new BufferedInputStream(in);
            bos = new BufferedOutputStream(fileOutputStream);

            //------------------------------------------------------我们自己写通常就是这么写的
            byte[] tmp = new byte[4096];
            int len;
            while ((len = bis.read(tmp)) != -1) {

                // 防止父文件夹被其他进程删除, 继续写入时造成父文件夹变为0字节文件的问题.
                if (!targetFile.getParentFile().exists()) {
                    targetFile.getParentFile().mkdirs();
                    throw new IOException("parent be deleted!");
                }

                bos.write(tmp, 0, len);
                current  = len;
                if (progressHandler != null) {
                    if (!progressHandler.updateProgress(total, current, false)) {
                        bos.flush();
                        throw new Callback.CancelledException("download stopped!");
                    }
                }
            }
            bos.flush();
        } finally {
            IOUtil.closeQuietly(bis);
            IOUtil.closeQuietly(bos);
        }

        return autoRename(targetFile);
    }

0 人点赞