Android简易音乐重构MVVM Java版 -搭建项目(八)
关于
本篇主要介绍,简易音乐重构,去掉butterkinfe,去掉mvp,精简代码优化逻辑,使用viewbinding和databinding,使用了Navigation导航组件来在部分页面跳转,升级项目版本工程版本,升级引用等等,但是最终我还是没有使用kotlin去重构这个项目,我是很想用kotlin写的,不管是出于个人目前对kotlin的热爱还是google对kotlin的支持,但是看起来目前对我这个moudle感兴趣的人用java的多点,所以这个项目目前还是用java去写,废话到此结束。
项目框架MVVM+Retrofit+RxJava+LiveData+viewbinding+databing+Navigation导航组件+other
新版本配置
Android studio 2021.2.1 Patch 1截至2022.6.14来说是稳定版的最新版
工程gradle是7.2.1,gradle-wrapper.properties里的gradle是7.3.3:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.2.1' apply false
id 'com.android.library' version '7.2.1' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
#Sat Jun 11 00:50:53 CST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
很多朋友可能会好奇三分的maven仓库啊jitpack库啊跑哪里去了,都跑到settings.gradle里面了:
这也是很大一个变动。
项目目标版本32,最低支持22
接下来是moudle里面的build的变化,:
android {
compileSdk 32
defaultConfig {
applicationId "com.tobery.personalmusic"
minSdk 22
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
dataBinding{
enabled true
}
viewBinding{
enabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
三方引用如下:
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:2.4.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.0"
//glide引用
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
//网络请求retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
//RxJava
implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
//RxAndroid
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
//Retrofit 支持Rxjava 的支持库
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//rxjava框架
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//音频
implementation 'com.github.EspoirX:StarrySky:v2.6.5'
// MultiDex的依赖
implementation 'androidx.multidex:multidex:2.0.0'
// Log、吐司打印
implementation 'com.github.getActivity:ToastUtils:10.3'
implementation 'com.github.Tobeyr1:DialogLoading:1.0.4'
//banner
implementation 'io.github.youth5201314:banner:2.2.2'
implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation 'com.github.Tobeyr1:liveDataCallAdapter:1.0.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
目前的引用就这么多,后续也会有加减。
网易云音乐api版本更新
api当然不是我做的了,我只是个使用者,GitHub地址,当然了,项目里也提供了可供使用的api网址
重构代码
(说明)其实项目是重新建的项目,然后对部分copy,大多数重新编写。
新建app类继承Application
public class app extends Application {
private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = Math.max(2,Math.min(CPU_COUNT-1,4));
private static app instance;
@Override
public void onCreate() {
super.onCreate();
instance = this;
ToastUtils.init(this, new BlackToastStyle());
CrashHandler.getInstance().init(this);
ExecutorService pool = Executors.newFixedThreadPool(CORE_POOL_SIZE);
pool.submit(new Runnable() {
@Override
public void run() {
MultiDex.install(instance);
mCountDownLatch.countDown();
}
});
pool.submit(new Runnable() {
@Override
public void run() {
StarrySky.init(instance).apply();
}
});
try {
//如果await之前没有调用countDown那么就会一直阻塞在这里
mCountDownLatch.await();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
项目结构
entity文件存放实体类,http则是网络请求的类api等,ui页面viewModel等,util则是一些帮助类等,widget存放的自定义view,暂时这样。
定义BaseActivity.java
public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//状态栏工具
StatusBarUtil.setColor(this,getResources().getColor(R.color.colorPrimary),0);
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
System.gc();
super.onDestroy();
}
}
状态栏工具
/**
* 2019年7月18日13:55:00
* 沉浸式管理工具类
*/
public class StatusBarUtil {
public static final String TAG = "StatusBarUtil";
private static final int DEFAULT_STATUS_BAR_ALPHA = 112;
private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.statusbarutil_fake_status_bar_view;
private static final int FAKE_TRANSLUCENT_VIEW_ID = R.id.statusbarutil_translucent_view;
private static final int TAG_KEY_HAVE_SET_OFFSET = -123;
/**
* 设置状态栏颜色
*
* @param activity 需要设置的 activity
* @param color 状态栏颜色值
*/
public static void setColor(Activity activity, @ColorInt int color) {
setColor(activity, color, DEFAULT_STATUS_BAR_ALPHA);
}
/**
* 设置状态栏颜色
* API等级19:Android 4.4 KitKat API等级20:Android 4.4W API等级21:Android 5.0 Lollipop
* API等级22:Android 5.1 Lollipop API等级23:Android 6.0 Marshmallow API等级24:Android 7.0 Nougat
*
* @param activity 需要设置的activity
* @param color 状态栏颜色值
* @param statusBarAlpha 状态栏透明度
*/
@SuppressLint("ObsoleteSdkInt")
public static void setColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {
//21以上
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));
//19到21
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//DecorView是顶级View,内部有titlebar和contentParent两个子元素,
// contentParent的id是content,而我们设置的main.xml布局则是contentParent里面的一个子元素
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
if (fakeStatusBarView != null) {
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
} else {
//第一次加载会先创建并添加
decorView.addView(createStatusBarView(activity, color, statusBarAlpha));
}
setRootView(activity);
}
}
/**
* 为滑动返回界面设置状态栏颜色
*
* @param activity 需要设置的activity
* @param color 状态栏颜色值
*/
public static void setColorForSwipeBack(Activity activity, int color) {
setColorForSwipeBack(activity, color, DEFAULT_STATUS_BAR_ALPHA);
}
/**
* 为滑动返回界面设置状态栏颜色
*
* @param activity 需要设置的activity
* @param color 状态栏颜色值
* @param statusBarAlpha 状态栏透明度
*/