RxPermissions mRxPermissions = new RxPermissions(this);
复制代码
//连续获取两个权限以上
mRxPermissions
.requestEach(Manifest.permission.CALL_PHONE,
Manifest.permission.BLUETOOTH)
.subscribe(new Consumer<Permission>() {
@Override
public void accept(Permission permission) throws Exception {
if (permission.granted) {
// 获取了权限
Toast.makeText(RxPermissionsActivity.this,
"获取两个权限",
Toast.LENGTH_SHORT).show();
} else if (permission.shouldShowRequestPermissionRationale) {
//没有获取权限,可是用户没有点不在询问
Toast.makeText(RxPermissionsActivity.this,
"权限拒绝,可是没有点不在询问",
Toast.LENGTH_SHORT).show();
} else {
//用户已经点了不在询问,须要去启动设置开启权限
Toast.makeText(RxPermissionsActivity.this,
"权限拒绝,而且不能询问",
Toast.LENGTH_SHORT).show();
}
}
},
new Consumer<Throwable>() {
@Override
public void accept(Throwable t) {
Timber.tag(getClassName()).i("发生异常" + t);
}
},
new Action() {
@Override
public void run() {
Timber.tag(getClassName()).i("完成");
}
});
复制代码
RxPermissions
的使用,我在实际工程中,没有使用过//使用RxView的简单的例子
disposable = RxView.clicks(findViewById(R.id.enableCamera))
// 单击按钮时请求权限
.compose(mRxPermissions.ensureEach(Manifest.permission.CAMERA))
.subscribe(new Consumer<Permission>() {
@Override
public void accept(Permission permission) {
Timber.tag(getClassName()).i("Permission result " + permission);
if (permission.granted) {
releaseCamera();
camera = Camera.open(0);
try {
camera.setPreviewDisplay(surfaceView.getHolder());
camera.startPreview();
} catch (IOException e) {
Timber.tag(getClassName()).i("IOException result " + e);
}
} else if (permission.shouldShowRequestPermissionRationale) {
Toast.makeText(RxPermissionsActivity.this,
"权限拒绝,可是没有点不在询问",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(RxPermissionsActivity.this,
"用户已经点了不在询问,须要去启动设置开启权限",
Toast.LENGTH_SHORT).show();
}
}
},
new Consumer<Throwable>() {
@Override
public void accept(Throwable t) {
Timber.tag(getClassName()).i("发生异常" + t);
}
},
new Action() {
@Override
public void run() {
Timber.tag(getClassName()).i("完成");
}
});
复制代码
buildTypes {
// timber 的配置 debuggable
release {
minifyEnabled false
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
}
}
复制代码
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
//也能够设置log一直开
Timber.plant(new DebugTree());
} else {
//上线的话 就关闭有些没必要要的日记输出
Timber.plant(new CrashReportingTree());
}
QMUISwipeBackActivityManager.init(this);
//打印tag为类名
Timber.v("---HementApplication ---");
}
复制代码
private static final class CrashReportingTree extends Timber.Tree {
@Override
protected boolean isLoggable(@Nullable String tag, int priority) {
return priority >=INFO;
}
@Override
protected void log(int priority, @org.jetbrains.annotations.Nullable String tag, @NotNull String message, @org.jetbrains.annotations.Nullable Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
FakeCrashLibrary.log(priority, tag, message);
if (t != null) {
if (priority == Log.ERROR) {
FakeCrashLibrary.logError(t);
} else if (priority == Log.WARN) {
FakeCrashLibrary.logWarning(t);
}
}
}
}
复制代码
我我的对Timber的理解就是 很是的简单,也很是的方便控制那些日志上线和Debug中不能够输出,虽然咱们本身也能够作到,可是Timer还有个其余的功能,能够和 %d
%s
一块儿使用java
%d
后面接上Long Int等类型 %s
后面接上字符串类型,在Hement的项目中,我是这样封装使用的android
在BaseActivity 中获取这个类名git
protected String getClassName(){
return this.getClass().getSimpleName();
}
复制代码
Timber.tag(getClassName()).i("建立新的configPersistentComponent id=%d",mActivityId);
Timber.tag(getClassName()).i("mMainPresenter =%s",mMainPresenter);
复制代码
sqlbrite
对 Android
系统的SQLiteOpenHelper
和 ContentResolver
的轻量级封装,配合Rxjava2
使用。sqlbrite
,完美解决数据库和UI
的同步更新!// 数据库
api 'com.squareup.sqlbrite3:sqlbrite:3.2.0'
复制代码
public class DB {
public DB() { }
public abstract static class HementTable {
public static final String TABLE_NAME = "hement";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_DATE = "date";
public static final String COLUMN_DAY = "day";
// 注意建立表的结构是否正确
public static final String CREATE =
"CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_TITLE + " TEXT NOT NULL, " +
COLUMN_DATE + " TEXT NOT NULL, " +
COLUMN_DAY + " TEXT NOT NULL" +
" ); ";
public static ContentValues toContentValues(TodayBean ribot) {
ContentValues values = new ContentValues();
values.put(COLUMN_TITLE, ribot.title);
values.put(COLUMN_DATE, ribot.date);
values.put(COLUMN_DAY, ribot.day);
return values;
}
public static TodayBean parseCursor(Cursor cursor) {
String title = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_TITLE));
String date = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_DATE));
String day = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_DAY));
TodayBean bean = new TodayBean();
bean.setDate(date);
bean.setTitle(title);
bean.setDay(day);
return bean;
}
}
复制代码
ContentValues
:该类用于存储处理的一组值,底层原理就是HashMap。ContentResolver
可以去处理,等于他们结合使用@Singleton
public class DbOpenHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "hement.db";
public static final int DATABASE_VERSION = 1;
@Inject
public DbOpenHelper(@ApplicationContext Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.beginTransaction();
try {
db.execSQL(DB.HementTable.CREATE);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
复制代码
@Singleton
public class DatabaseHelper {
private final BriteDatabase mDb;
@Inject
public DatabaseHelper(DbOpenHelper dbOpenHelper) {
this(dbOpenHelper, Schedulers.io());
}
public DatabaseHelper(DbOpenHelper dbOpenHelper, Scheduler scheduler) {
SqlBrite.Builder briteBuilder = new SqlBrite.Builder();
mDb = briteBuilder.build().wrapDatabaseHelper(dbOpenHelper, scheduler);
}
public BriteDatabase getDb() {
return mDb;
}
/**
* 保存数据库中的数据,这个数据的来源是网络请求
* @param newRibots
* @return
*/
public Observable<TodayBean> setDBData(final List<TodayBean> newRibots) {
return Observable.create(new ObservableOnSubscribe<TodayBean>() {
@Override
public void subscribe(ObservableEmitter<TodayBean> emitter) throws Exception {
if (emitter.isDisposed()) return;
BriteDatabase.Transaction transaction = mDb.newTransaction();
try {
mDb.delete(DB.HementTable.TABLE_NAME, null);
for (TodayBean ribot : newRibots) {
long result = mDb.insert(DB.HementTable.TABLE_NAME,
DB.HementTable.toContentValues(ribot),
SQLiteDatabase.CONFLICT_REPLACE);
if (result >= 0) emitter.onNext(ribot);
}
transaction.markSuccessful();
emitter.onComplete();
} finally {
transaction.end();
}
}
});
}
/**
* 获取数据库中的数据
* @return
*/
public Observable<List<TodayBean>> getDBData() {
return mDb.createQuery(DB.HementTable.TABLE_NAME,
"SELECT * FROM " + DB.HementTable.TABLE_NAME)
.mapToList(new Function<Cursor, TodayBean>() {
@Override
public TodayBean apply(@NonNull Cursor cursor) throws Exception {
return DB.HementTable.parseCursor(cursor);
}
});
}
}
复制代码
retrofit converter-gson adapter-rxjava2 rxandroid rxjava logging-interceptorgithub
QMUI Android
的设计目的是用于辅助快速搭建一个具有基本设计还原效果的Android
项目,同时利用自身提供的丰富控件及兼容处理,让开发者能专一于业务需求而无需耗费精力在基础代码的设计上。不论是新项目的建立,或是已有项目的维护,都可使开发效率和项目质量获得大幅度提高。sql
功能特性数据库
在此感谢QMUI的小伙伴无私贡献api
未完待续 下一篇文章bash
GitHub地址:Hement:持续更新中网络
因为使用Dagger2的未知性,因此建立一个分支没有使用Dagger2 Hement架构
感谢一下博客对个人帮助