Android全能开源项目xUtils3开发教程、简单封装

简介: Android全能开源项目xUtils3开发教程、简单封装一、简介xUtils是一个比较全能的开源项目了, 包含了orm, http(s), image, view注解, 但依然很轻量级(246K), 并且特性强大, 方便扩展。

Android全能开源项目xUtils3开发教程、简单封装

一、简介

xUtils是一个比较全能的开源项目了, 包含了orm, http(s), image, view注解, 但依然很轻量级(246K), 并且特性强大, 方便扩展。这是xUtils3 的 github地址https://github.com/wyouflf/xUtils3

xUtils3 的一些特性

  • xUtils支持超大文件(超过2G)上传,更全面的http请求协议支持(11种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响;
  • xUtils3变化较多所以建立了新的项目不在旧版(github.com/wyouflf/xUtils)上继续维护, 相对于旧版本:
    (1)HTTP实现替换HttpClient为UrlConnection, 自动解析回调泛型, 更安全的断点续传策略;
    (2)支持标准的Cookie策略, 区分domain, path;
    (3)事件注解去除不常用的功能, 提高性能;
    (4)数据库api简化提高性能, 达到和greenDao一致的性能;
    (5)图片绑定支持gif(受系统兼容性影响, 部分gif文件只能静态显示), webp; 支持圆角, 圆形, 方形等裁剪, 支持自动旋转。

二、环境搭建

在build.gradle中加入如下依赖,编写文章时,最新版本为3.5.0,可以到github或者maven仓库查询最新版本。

//gradle4.4之前
compile 'org.xutils:xutils:3.5.0'
//gradle4.4之后
implementation 'org.xutils:xutils:3.5.0'

需要的权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

配置


public class TRApplicaction extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        x.Ext.init(this);
        x.Ext.setDebug(BuildConfig.DEBUG); // 是否输出debug日志, 开启debug会影响性能.
    }
}

在AndroidManifest文件中注册TRApplicaction

 <application
        android:name=".TRApplicaction"
        .../>
 </application>       

三、注解模块的使用

xUtils3自动注入注解 @ViewInject 真的是很好用,这样就不用一个个findById去注入组件了。

  • Activity中注解的使用
@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
    cc(R.id.viewpager)
    ViewPager viewPager;  //自动注入,不需要findById了
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main); //使用@ContentView注解就不需要了
        x.view().inject(MainActivity.this); //这里尽量吧类名加上
        ...
    }
}
  • Fragment中注解的使用
@ContentView(R.layout.fragment_home)
public class HomeFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return x.view().inject(this, inflater, container);
    }
    @Override
    public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(v, savedInstanceState);
    }
}
  • 绑定事件
/**
 * 1. 方法必须私有限定,
 * 2. 方法参数形式必须和type对应的Listener接口一致.
 * 3. 注解参数value支持数组: value={id1, id2, id3}
 * 4. 其它参数说明见{@link org.xutils.event.annotation.Event}类的说明.
 **/
@Event({R.id.new_model_btn,...})
private void onClick(View v){
    ....
}

四、网络请求

由于Android6.0版本之后将HttpClient替换为UrlConnection,所以修改老项目的时候一定要注意。
这里我们简单封装一下, 请求参数通过map传过来,然后通过回调返回请求结果。

/**
 * @author nelson
 */
public class c {
    private static  final String BASE_URL = "http://10.168.11.11/";
    
    public static void get(String url, Map<String, Object> parms, final GetDataCallback callback) {
        RequestParams params = new RequestParams(GetDataTask.BASE_URL + url);
        if(parms!=null){
            for (String key : parms.keySet()) {
                params.addParameter(key, parms.get(key));
            }
        }
        x.http().get(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                callback.success(result);
            }
            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                callback.failed();
            }
            @Override
            public void onCancelled(CancelledException cex) {}
            @Override
            public void onFinished() {}
        });
    }

    public static void post(String url, Map<String, Object> parms, final GetDataCallback callback) {
        RequestParams params = new RequestParams(GetDataTask.BASE_URL + url);
        if(parms!=null){
            for (String key : parms.keySet()) {
                params.addParameter(key, parms.get(key));
            }
        }
        x.http().post(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                if(callback!=null){
                    callback.success(result);
                }
            }
            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                if(callback!=null){
                    callback.failed();
                }
            }
            @Override
            public void onCancelled(CancelledException cex) {}
            @Override
            public void onFinished() {}
        });
    }
    /**上传文件*/
    public static void uplodFile(List<String> path, Map<String, Object> map, final GetDataCallback callback) {
        RequestParams params = new RequestParams(GetDataTask.BASE_URL+"upload");
        params.setMultipart(true);
        for (String key : map.keySet()) {
            params.addBodyParameter(key, map.get(key).toString());
        }
        for (int i = 0; i < path.size(); i++) {
            params.addBodyParameter("uploadfile" + i, new File(path.get(i)));
        }
        x.http().post(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                callback.success(result);
            }
            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                callback.failed();
            }
            @Override
            public void onCancelled(CancelledException cex) {}
            @Override
            public void onFinished() {}
        });
    }
    /**回调接口*/
    public interface GetDataCallback {
        void success(String result);
        void failed(String... args);
    }
}

发起网络请求

Map<String,Object> map = new HashMap<>();
map.put("pageNumber",page);
map.put("typeid",typeid);
//如果请求不需要参数,传null
// GetDataTask.post("app/types", null, new GetDataTask.GetDataCallback(){}
GetDataTask.post("app/types", map, new GetDataTask.GetDataCallback() {
   @Override
   public void success(String response) {
       Gson gson = new Gson(); //后台返回来的json格式,其他格式自己处理
       Result result = gson.fromJson(response, Result.class);
   }
   @Override
   public void failed(String... args) {
   }
});

五、绑定图片

//通过ImageOptions.Builder().set方法设置图片的属性
ImageOptions imageOptions= new ImageOptions.Builder().setFadeIn(true).build(); //淡入效果
    //ImageOptions.Builder()的一些其他属性:
    .setCircular(true) //设置图片显示为圆形
    .setSquare(true) //设置图片显示为正方形
    .setCrop(true).setSize(200,200) //设置大小
    .setAnimation(animation) //设置动画
    .setFailureDrawable(Drawable failureDrawable) //设置加载失败的动画
    .setFailureDrawableId(int failureDrawable) //以资源id设置加载失败的动画
    .setLoadingDrawable(Drawable loadingDrawable) //设置加载中的动画
    .setLoadingDrawableId(int loadingDrawable) //以资源id设置加载中的动画
    .setIgnoreGif(false) //忽略Gif图片
    .setParamsBuilder(ParamsBuilder paramsBuilder) //在网络请求中添加一些参数
    .setRaduis(int raduis) //设置拐角弧度
    .setUseMemCache(true) //设置使用MemCache,默认true

x.image().bind(imageView, url, imageOptions);
// assets file
x.image().bind(imageView, "assets://test.gif", imageOptions);
// local file
x.image().bind(imageView, new File("/sdcard/test.gif").toURI().toString(), imageOptions);
x.image().bind(imageView, "/sdcard/test.gif", imageOptions);
x.image().bind(imageView, "file:///sdcard/test.gif", imageOptions);
x.image().bind(imageView, "file:/sdcard/test.gif", imageOptions);
x.image().bind(imageView, url, imageOptions, new Callback.CommonCallback<Drawable>() {
    @Override
    public void onSuccess(Drawable result) {
    }
    @Override
    public void onError(Throwable ex, boolean isOnCallback) {
    }
    @Override
    public void onCancelled(CancelledException cex) {
    }
    @Override
    public void onFinished() {
    }
x.image().loadDrawable(url, imageOptions, new Callback.CommonCallback<Drawable>() {...});
// 用来获取缓存文件
x.image().loadFile(url, imageOptions, new Callback.CommonCallback<File>() {...});

六、异步执行任务

x.task().run(new Runnable() {
    @Override
    public void run() {
        //异步任务
    }
});
x.task().post(new Runnable() { 
    @Override
    public void run() {
        //同步代码
    }
});

七、ORM 数据库操作

Application中进行初始化配置DaoConfig


DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
        //设置数据库名,默认xutils.db
        .setDbName("myapp.db")
        //设置数据库路径,默认存储在app的私有目录
        .setDbDir(new File("/mnt/sdcard/"))
        //设置数据库的版本号
        .setDbVersion(2)
        //设置数据库打开的监听
        .setDbOpenListener(new DbManager.DbOpenListener() {
            @Override
            public void onDbOpened(DbManager db) {
                //开启数据库支持多线程操作,提升性能,对写入加速提升巨大
                db.getDatabase().enableWriteAheadLogging();
            }
        })
        //设置数据库更新的监听
        .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
            @Override
            public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
            }
        })
        //设置表创建的监听
        .setTableCreateListener(new DbManager.TableCreateListener() {
            @Override
            public void onTableCreated(DbManager db, TableEntity<?> table){
                Log.i("JAVA", "onTableCreated:" + table.getName());
            }
        });

操作数据库

// User类在最底下
DbManager db = x.getDb(daoConfig);
db.dropDb(); // 删除数据库
db.dropTable(User.class); // 删除表
db.save(new User("nelson")); //新增数据
db.delete(User.class); //mtb_user表中数据将被全部删除
//条件删除:
WhereBuilder b = WhereBuilder.b();
b.and("id",">",2); //构造修改的条件
b.and("id","<",4);
db.delete(User.class, b);

修改数据

//第一种写法:
ChildInfo first = db.findFirst(ChildInfo.class);
first.setcName("zhansan2");
db.update(first,"c_name"); //c_name:表中的字段名
//第二种写法:
WhereBuilder b = WhereBuilder.b();
b.and("id","=",first.getId()); //构造修改的条件
KeyValue name = new KeyValue("c_name","zhansan3");
db.update(ChildInfo.class,b,name);
//第三种写法:
first.setcName("zhansan4");
db.saveOrUpdate(first);

条件查询

Parent test = db.selector(Parent.class).where("id", "in", new int[]{1, 3, 6}).findFirst();
long count = db.selector(Parent.class).where("name", "LIKE", "w%").and("age", ">", 32).count();
List<Parent> testList = db.selector(Parent.class).where("id", "between", new String[]{"1", "5"}).findAll();
@Table(name = "mtb_user",onCreated = "")
public class User {
    /**
     * name = "id":数据库表中的一个字段
     * isId = true:是否是主键
     * autoGen = true:是否自动增长
     * property = "NOT NULL":添加约束
     */
    @Column(name = "id",isId = true,autoGen = true,property = "NOT NULL")
    private int id;
    @Column(name = "username")
    private String username;
    ......
}

关注

如果有问题,请在下方评论,或者加群讨论 200909980

关注下方微信公众号,可以及时获取到各种技术的干货哦,如果你有想推荐的帖子,也可以联系我们的。

img_5a253571436dadabbacddb297a06dce0.png
这里写图片描述
相关文章
|
25天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
51 19
|
25天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
54 14
|
28天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
26天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
32 5
|
25天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
|
26天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
26天前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
29天前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
26天前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
35 0
|
29天前
|
存储 监控 Java
探索安卓开发:从基础到进阶的旅程
在这个数字时代,移动应用已成为我们日常生活的一部分。对于开发者来说,掌握安卓开发不仅是技能的提升,更是通往创新世界的钥匙。本文将带你了解安卓开发的核心概念,从搭建开发环境到实现复杂功能,逐步深入安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的见解和技巧,帮助你在安卓开发的道路上更进一步。
25 0