正在研究
- SUtils 封装有许多实用的开发工具类
- APKParser
- parceler通过注解的方式序列化对象
more: Transfuse Transfuse is a Java Dependency Injection (DI) and integration library geared specifically for the Google Android API.
数据持久化
- Awesome-Android-Persistence 数据持久化优秀的开源库列表 【重点】
- android-sqlite-asset-helper
数据处理
- 汉字转拼音库 用于对人名进行排序
Gson
导入
dependencies {
implementation 'com.google.code.gson:gson:2.8.4'
}
序列化/反序列化
Array<=> json
String namesJson = "['xiaoqiang','chenrenxiang','hahaha']";
Gson gson = new Gson();
String[] nameArray = gson.fromJson(namesJson, String[].class);
json => list
String userJson = "[{'isDeveloper':false,'name':'xiaoqiang','age':26,'email':'578570174@qq.com'},{'isDeveloper':true,'name':'xiaoqiang123','age':27,'email':'578570174@gmail.com'}]";
Gson gson = new Gson();
Type userListType = new TypeToken<ArrayList<User>>(){}.getType();
List<User> userList = gson.fromJson(userJson, userListType);
控制序列化/反序列化的变量名称
public class User {
@Expose()
String name; // 参与序列化/反序列化
@Expose(serialize = false, deserialize = false)
String email; // 不参与序列化,也不参与反序列化
@Expose(serialize = false)
int age; // 只参与反序列化
@Expose(deserialize = false)
boolean isDeveloper; // 只参与序列化
@SerializedName(value = "name", alternate = "fullName")
String userName ;
}
注意:使用以上必须使用如下
GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithoutExposeAnnotation();
Gson gson = builder.create();
字段值为 null 时是否序列化
/**
* Person 实体一共4个字段:Integer pId、String pName、Date birthday、Boolean isMarry
* 现在它的属性全部不进行赋值
*/
Person person = new Person();
/** 不对属性值为 null 的字段进行序列化,转换结果会为空*/
String personStr = new Gson().toJson(person);
/** 对属性值为 null 的字段进行序列化*/
String personStrFinal = new GsonBuilder().serializeNulls().create().toJson(person);
System.out.println(personStr);
//输出:{}
System.out.println(personStrFinal);
TypeAdapter
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Book.class, new BookTypeAdapter());
final Gson gson = gsonBuilder.create();
/**
* Integer 转换 防止 后台返回null 转换异常
*/
public class IntegerDefaultAdapter extends TypeAdapter<Integer> {
@Override
public void write(JsonWriter jsonWriter, Integer integer) throws IOException {
jsonWriter.value(String.valueOf(integer));
}
@Override
public Integer read(JsonReader jsonReader) throws IOException {
try {
return Integer.valueOf(jsonReader.nextString());
} catch (NumberFormatException e) {
e.printStackTrace();
return -1;
}
}
}
/**
* String 转换 防止 后台返回null 转换异常
*/
public class StringDefaultAdapter extends TypeAdapter<String> {
@Override
public void write(JsonWriter jsonWriter, String s) throws IOException {
jsonWriter.value(s);
}
@Override
public String read(JsonReader jsonReader) throws IOException {
if (jsonReader.peek() == JsonToken.NULL) {
jsonReader.nextNull();
return "";
} else {
return jsonReader.nextString();
}
}
}
直接操作JSON
【重点】方法根据不同Json类型进行解析
parse.isJsonArray();
parse.isJsonNull();
parse.isJsonObject();
parse.isJsonPrimitive();
常用操作JsonObject
String jsonStr = "{\"pId\":9527,\"pName\":\"华安\",\"birthday\":\"Nov 23, 2018 1:50:56 PM\",\"isMarry\":true}";
JsonParser jsonParser = new JsonParser();
/**
* JsonElement parse(String json)
* 如果被解析的字符串不符合 json 格式,则抛出异常
* */
JsonObject jsonObject = jsonParser.parse(jsonStr).getAsJsonObject();
/**
* JsonElement get(String memberName)
* 注意:如果 get 的 key 不存在,则返回 null,如果不加判断而进行取值的话,会抛:java.lang.NullPointerException
* */
Integer pId = jsonObject.get("pId").getAsInt();
JsonArray
String jsonArrayStr = "[{\"pId\":9527,\"pName\":\"华安\",\"isMarry\":true},{\"pId\":8866,\"pName\":\"宁王\",\"isMarry\":false}]";
JsonParser jsonParser = new JsonParser();
JsonArray jsonArray = jsonParser.parse(jsonArrayStr).getAsJsonArray();
构建JSON
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("pId", 9527);
jsonObject.addProperty("pName", "华安");
jsonObject.addProperty("isMarry", true);
//JsonObject 添加复杂类型属性使用
//add(String property, JsonElement value)
//JsonObject 与 JsonArray 都是 JsonElement 类的子类
构建工具
MultiChannelPackageTool 快速多渠道打包工具。
开发中实用的工具
- RoboGif A small utility to record Android device screen to a GIF
- AppUninstall Android App监听自身卸载,反馈统计
- LogCollector 一个收集 app 输出日志的工具
UI
- AndroidDesignPreview
- AndroidAssetStudio Android常用图标生成Web
- 切图标记外挂神器 Assistor PS 介绍
- 动态修改App字符开源库 Philology
主题
显示效果
- 闪光 Shimmer
- shimmer-recyclerview-x 闪光list
- shimmer-recyclerview-x 闪光list
未读消息
implementation 'q.rorbin:badgeview:1.1.3'
使用
new QBadgeView(context).bindTarget(textview).setBadgeNumber(5);
https://github.com/qstumn/BadgeView
检测优化工具
- LeakCanary Android 和 Java 内存泄露检测
Tutorial ChineseEnglish
phrof file path: /storage/sdcard0/Download/leakcanary/
hprof-conv leakCanary - apk-method-count 上传Apk,可以根据包名统计方法数量的网站,UI很友好。
- battery-historian Google 官网方 针对 Api21 5.0以上系统开发的电量使用情况分析工具
功能性开发工具
card.io-Android-source 信用卡扫描SDK
reprint A simple, unified fingerprint authentication library for Android with ReactiveX extensions.
DimensCodeTools 一个可以支持生成二维码,条形码和扫描的库
Permission
- Dexter Dexter is an Android library that simplifies the process of requesting permissions at runtime.
- PermissionHelper
- easypermissions
图片加载
Picasso
Universal-ImageLoader
Volley
Glide Tutorial Chinese
综合: 开源组件加载网络图片的优缺点比较FileDownload
- Android-Download-Manager-Pro
- MultiThreadDownloader 下载
- FileDownloader Multitask、Breakpoint-resume、High-concurrency、Simple to use、Single-process
Once some info may show once in a new app in a update or first time install this via share sharedPreferences sore the timestamp
基础的开发工具
- JavaVerbalExpressions Java regular expressions made easy. 帮助简单的实现正则表达
- joda-time-android/ThreeTenABP Java8 的Date包移植到Android中来的库
- MathView A library for displaying math formula in Android apps.
崩溃错误处理
LoadSir 优雅地处理加载中,重试,无数据等
配置: compile ‘com.kingja.loadsir:loadsir:1.3.6’
ProGuard:
-dontwarn com.kingja.loadsir.**
-keep class com.kingja.loadsir.** {*;}
YCStateLayout 特殊状态提示
状态切换,让 View 状态的切换和 Activity 彻底分离开。
BufferKnife
布局绑定
static class ViewHolder {
@BindView(R.id.form_start_date_tv) TextView formStartDateTv;
ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
VIEW LISTS
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })
@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
// The apply method allows you to act on all the views in a list at once.
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
//Action and Setter interfaces allow specifying simple behavior.
static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
@Override public void apply(View view, int index) {
view.setEnabled(false);
}
};
static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
@Override public void set(View view, Boolean value, int index) {
view.setEnabled(value);
}
};
An Android Property
can also be used with the apply
method.ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
RESOURCE BINDING
class ExampleActivity extends Activity {
@BindString(R.string.title) String title;
@BindDrawable(R.drawable.graphic) Drawable graphic;
@BindColor(R.color.red) int red; // int or ColorStateList field
@BindDimen(R.dimen.spacer) Float spacer; // int (for pixel size) or float (for exact value) field
// ...
}
automatically be cast.
@OnClick(R.id.submit)
public void sayHi(Button button) {
button.setText("Hello!");
}
OPTIONAL BINDINGS
@Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
// TODO ...
}
BINDING RESET on Fragments
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
unbinder = ButterKnife.bind(this, view);
// TODO Use fields...
return view;
}
@Override public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
模块化的开发工具
- AndroidFilePicker FilePicker 是一个小巧快速的文件选择器框架,以快速集成、高自定义化和可配置化为目标不断前进
网络工具
- r0capture 安卓应用层抓包通杀脚本
翻遍工具
- android-classyshark
mac/win 使用 java -jar ClassyShark.jar