├── .gitignore
├── .idea
├── .gitignore
├── .name
├── compiler.xml
├── gradle.xml
├── jarRepositories.xml
├── misc.xml
├── modules
│ └── apm
│ │ ├── MikelProjectDemo.apm.androidTest.iml
│ │ └── MikelProjectDemo.apm.unitTest.iml
└── vcs.xml
├── README.md
├── apmlib
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mikel
│ │ └── apmlib
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── com
│ │ └── mikel
│ │ └── apmlib
│ │ ├── MatrixDynamicConfigImpl.java
│ │ ├── MatrixManager.java
│ │ └── MatrixPluginListener.java
│ └── test
│ └── java
│ └── com
│ └── mikel
│ └── apmlib
│ └── ExampleUnitTest.java
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mikel
│ │ └── projectdemo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── mikel
│ │ │ └── projectdemo
│ │ │ ├── MainActivity.java
│ │ │ ├── apm
│ │ │ ├── ApmAnrTestService.java
│ │ │ ├── ApmTestActivity.java
│ │ │ └── ApmTouchEventTestActivity.java
│ │ │ ├── application
│ │ │ ├── AppRuntime.java
│ │ │ ├── AppRuntimeForMain.java
│ │ │ ├── AppRuntimeForVideo.java
│ │ │ ├── AppRuntimeForWeb.java
│ │ │ └── BaseApplication.java
│ │ │ ├── jetpack
│ │ │ ├── service
│ │ │ │ ├── db
│ │ │ │ │ ├── dao
│ │ │ │ │ │ ├── PoetryDao.java
│ │ │ │ │ │ └── RemoteKeyDao.java
│ │ │ │ │ └── database
│ │ │ │ │ │ └── AppDatabase.java
│ │ │ │ ├── model
│ │ │ │ │ ├── Poetry.java
│ │ │ │ │ ├── RemoteKey.java
│ │ │ │ │ ├── Result.java
│ │ │ │ │ └── ResultList.java
│ │ │ │ ├── network
│ │ │ │ │ ├── CustomLoggingInterceptor.java
│ │ │ │ │ ├── PagingNetWorkApiService.java
│ │ │ │ │ └── RetrofitManager.java
│ │ │ │ ├── paging2
│ │ │ │ │ ├── LocalPageKeyedDataSource.java
│ │ │ │ │ ├── LocalPageKeyedDataSourceFactory.java
│ │ │ │ │ ├── NetPagedKeyedDataSource.java
│ │ │ │ │ └── NetPagedKeyedDataSourceFactory.java
│ │ │ │ ├── paging3
│ │ │ │ │ ├── PagingRemoteMediator.java
│ │ │ │ │ └── PoetryListPagingSource.java
│ │ │ │ ├── repository
│ │ │ │ │ └── RepositoryManager.java
│ │ │ │ └── utils
│ │ │ │ │ ├── Constants.java
│ │ │ │ │ └── Utils.java
│ │ │ ├── view
│ │ │ │ ├── adapter
│ │ │ │ │ ├── CustomBindingAdapter.java
│ │ │ │ │ ├── PoetryListAdapterForPaging2.java
│ │ │ │ │ └── PoetryListAdapterForPaging3.java
│ │ │ │ ├── callback
│ │ │ │ │ └── PoetryClickCallBack.java
│ │ │ │ └── ui
│ │ │ │ │ ├── Paging2MainActivity.java
│ │ │ │ │ ├── Paging3MainActivity.java
│ │ │ │ │ ├── PoetryDetailActivity.java
│ │ │ │ │ ├── PoetryFragment.java
│ │ │ │ │ ├── PoetryListFragmentForPaging2Local.java
│ │ │ │ │ ├── PoetryListFragmentForPaging2Network.java
│ │ │ │ │ └── PoetryListFragmentForPaging3.java
│ │ │ └── viewmodel
│ │ │ │ ├── PoetryListViewModelForPaging2Local.java
│ │ │ │ ├── PoetryListViewModelForPaging2Network.java
│ │ │ │ ├── PoetryListViewModelForPaging3.java
│ │ │ │ └── PoetryViewModel.java
│ │ │ ├── media
│ │ │ └── video
│ │ │ │ ├── VideoFileNameGenerator.java
│ │ │ │ ├── VideoPlayManager.java
│ │ │ │ ├── VideoPlayTask.java
│ │ │ │ └── VideoViewPagerAdapter.java
│ │ │ ├── presenter
│ │ │ └── FileHandlePresenter.java
│ │ │ ├── uiframework
│ │ │ ├── BaseViewPagerAdapter.java
│ │ │ ├── JetPackFragment.java
│ │ │ ├── MainFragment.java
│ │ │ ├── MainViewPagerAdapter.java
│ │ │ ├── MediaFragment.java
│ │ │ ├── TabSubViewPagerAdapter.java
│ │ │ ├── VideoTestFragment.java
│ │ │ └── subtab
│ │ │ │ ├── SubTabFragment1.java
│ │ │ │ ├── SubTabFragment2.java
│ │ │ │ └── SubTabFragment3.java
│ │ │ ├── utils
│ │ │ ├── CPUUtil.java
│ │ │ ├── FileHelper.java
│ │ │ └── MemoryUtil.java
│ │ │ ├── video
│ │ │ └── VideoTestActivity.java
│ │ │ └── web
│ │ │ └── WebViewTestActivity.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ └── image.jpg
│ │ ├── layout
│ │ ├── activity_apm.xml
│ │ ├── activity_detail_poetry.xml
│ │ ├── activity_main.xml
│ │ ├── activity_paging2_main.xml
│ │ ├── activity_paging3_main.xml
│ │ ├── activity_touch_event_test.xml
│ │ ├── activity_video_test.xml
│ │ ├── fragment_jetpack_main.xml
│ │ ├── fragment_main.xml
│ │ ├── fragment_media.xml
│ │ ├── fragment_poetry_detail.xml
│ │ ├── fragment_poetry_list.xml
│ │ ├── fragment_sub_tab_content1.xml
│ │ ├── fragment_sub_tab_content2.xml
│ │ ├── fragment_sub_tab_content3.xml
│ │ ├── fragment_sub_tab_title1.xml
│ │ ├── fragment_sub_tab_title2.xml
│ │ ├── fragment_sub_tab_title3.xml
│ │ ├── fragment_tab_jetpack.xml
│ │ ├── fragment_tab_main.xml
│ │ ├── fragment_tab_media.xml
│ │ ├── fragment_video_item.xml
│ │ ├── layout_bottom_sheet_image_video.xml
│ │ └── poetry_list_item.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ └── network_security_config.xml
│ └── test
│ └── java
│ └── com
│ └── mikel
│ └── projectdemo
│ └── ExampleUnitTest.java
├── baselib
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mikel
│ │ └── baselib
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── com
│ │ └── mikel
│ │ └── baselib
│ │ ├── manager
│ │ └── ThreadManager.java
│ │ └── utils
│ │ ├── AppUtil.java
│ │ └── DisplayUtil.java
│ └── test
│ └── java
│ └── com
│ └── mikel
│ └── baselib
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── mmkv
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── mikel
│ └── mmkv
│ ├── IMMKVProvider.java
│ ├── MMKVProvider.java
│ ├── MMKVSP.java
│ └── MMKVUtils.java
├── nativelib
├── .cxx
│ ├── abi_configuration_5g453p2q.json
│ ├── abi_configuration_5g453p2q.log
│ ├── abi_configuration_5g453p2q_key.json
│ ├── cmake
│ │ └── debug
│ │ │ └── arm64-v8a
│ │ │ ├── CMakeCache.txt
│ │ │ ├── CMakeFiles
│ │ │ ├── 3.10.2
│ │ │ │ ├── CMakeCCompiler.cmake
│ │ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ │ └── CMakeSystem.cmake
│ │ │ ├── CMakeOutput.log
│ │ │ ├── TargetDirectories.txt
│ │ │ ├── cmake.check_cache
│ │ │ ├── feature_tests.bin
│ │ │ ├── feature_tests.c
│ │ │ └── feature_tests.cxx
│ │ │ ├── android_gradle_build.json
│ │ │ ├── android_gradle_build_mini.json
│ │ │ ├── build.ninja
│ │ │ ├── build_command.txt
│ │ │ ├── build_file_index.txt
│ │ │ ├── build_model.json
│ │ │ ├── cmake_install.cmake
│ │ │ ├── cmake_server_log.txt
│ │ │ ├── compile_commands.json
│ │ │ ├── compile_commands.json.bin
│ │ │ ├── json_generation_record.json
│ │ │ ├── prefab_config.json
│ │ │ ├── rules.ninja
│ │ │ └── symbol_folder_index.txt
│ ├── ndk_locator_record_17146en5.json
│ ├── ndk_locator_record_17146en5.log
│ ├── ndk_locator_record_17146en5_key.json
│ ├── ndk_locator_record_1l5e415f.json
│ ├── ndk_locator_record_1l5e415f.log
│ └── ndk_locator_record_1l5e415f_key.json
├── .gitignore
├── CMakeLists.txt
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
├── readme.txt
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mikel
│ │ └── natvelib
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── cpp
│ │ ├── include
│ │ │ └── aes.h
│ │ └── native_test.cpp
│ ├── java
│ │ └── com
│ │ │ └── mikel
│ │ │ └── nativelib
│ │ │ └── JNIHelper.java
│ └── jniLibs
│ │ ├── arm64-v8a
│ │ └── libaesutil.so
│ │ └── armeabi-v7a
│ │ └── libaesutil.so
│ └── test
│ └── java
│ └── com
│ └── mikel
│ └── natvelib
│ └── ExampleUnitTest.java
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .gradle/
3 | out/
4 | obj/
5 | bin/
6 | gen/
7 | build/
8 | node_modules
9 | .classpath
10 | .project
11 | .DS_Store
12 | .settings
13 | local.properties
14 | *.iml
15 | .directory
16 | \#*
17 | *~
18 | *.swp
19 | *.hprof
20 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | MikelProjectDemo
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
24 |
25 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/modules/apm/MikelProjectDemo.apm.androidTest.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules/apm/MikelProjectDemo.apm.unitTest.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 该工程主要是个人学习和实践 android 技术 的 Demo 集成
2 |
3 | MVVM: ViewModel+LiveData+DataBinding+Retrofit+Room+Paging+RxJava 总结与实践(Java实现)
4 | https://blog.csdn.net/xiaobaaidaba123/article/details/88667506?spm=1001.2014.3001.5501
5 |
6 | android 嵌套ViewPager + Fragment实现仿头条UI框架Demo
7 | https://blog.csdn.net/xiaobaaidaba123/article/details/120595850
8 |
9 | Android 使用ViewPager2+ExoPlayer+VideoCache 实现仿抖音视频翻页播放
10 | https://blog.csdn.net/xiaobaaidaba123/article/details/120630087
11 |
12 | Android 11 拍照+录制视频保存到外部共享区域
13 | https://blog.csdn.net/xiaobaaidaba123/article/details/121585680?spm=1001.2014.3001.5501
14 |
15 | Android 11 从沙盒拷贝文件到外部共享存储区域
16 | https://blog.csdn.net/xiaobaaidaba123/article/details/121574807?spm=1001.2014.3001.5501
17 |
18 | Android 11 从外部存储读取文件到应用沙盒存储
19 | https://blog.csdn.net/xiaobaaidaba123/article/details/121441921?spm=1001.2014.3001.5501
20 |
21 | Android 固定大小WebView加载的H5页面
22 | https://blog.csdn.net/xiaobaaidaba123/article/details/122377262
23 |
--------------------------------------------------------------------------------
/apmlib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/apmlib/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 |
5 | android {
6 | compileSdkVersion 34
7 |
8 | defaultConfig {
9 | minSdkVersion 21
10 | targetSdkVersion 34
11 |
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | consumerProguardFiles "consumer-rules.pro"
14 | }
15 |
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 | compileOptions {
23 | sourceCompatibility JavaVersion.VERSION_1_8
24 | targetCompatibility JavaVersion.VERSION_1_8
25 | }
26 | }
27 |
28 | dependencies {
29 | //todo matrix
30 | implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: lib_thirds_matrix_version, changing: true
31 | implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: lib_thirds_matrix_version, changing: true
32 | implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: lib_thirds_matrix_version, changing: true
33 | // implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: lib_thirds_matrix_version, changing: true
34 | // implementation group: "com.tencent.matrix", name: "matrix-resource-canary-android", version: lib_thirds_matrix_version, changing: true
35 | // implementation group: "com.tencent.matrix", name: "matrix-resource-canary-common", version: lib_thirds_matrix_version, changing: true
36 | // implementation group: "com.tencent.matrix", name: "matrix-sqlite-lint-android-sdk", version: lib_thirds_matrix_version, changing: true
37 | // implementation group: "com.tencent.matrix", name: "matrix-battery-canary", version: lib_thirds_matrix_version, changing: true
38 | // implementation group: "com.tencent.matrix", name: "matrix-hooks", version: lib_thirds_matrix_version, changing: true
39 | // implementation group: "com.tencent.matrix", name: "matrix-backtrace", version: lib_thirds_matrix_version, changing: true
40 |
41 | implementation 'androidx.appcompat:appcompat:1.4.2'
42 | implementation 'com.google.android.material:material:1.6.1'
43 | testImplementation 'junit:junit:4.13.2'
44 | androidTestImplementation 'androidx.test.ext:junit:1.1.3'
45 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
46 | }
--------------------------------------------------------------------------------
/apmlib/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/apmlib/consumer-rules.pro
--------------------------------------------------------------------------------
/apmlib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/apmlib/src/androidTest/java/com/mikel/apmlib/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.mikel.apmlib;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.mikel.apmlib.test", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/apmlib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/apmlib/src/main/java/com/mikel/apmlib/MatrixDynamicConfigImpl.java:
--------------------------------------------------------------------------------
1 | package com.mikel.apmlib;
2 | import com.tencent.mrs.plugin.IDynamicConfig;
3 |
4 | public class MatrixDynamicConfigImpl implements IDynamicConfig {
5 | public MatrixDynamicConfigImpl() {}
6 |
7 | public boolean isFPSEnable() { return true;}
8 | public boolean isTraceEnable() { return true; }
9 | public boolean isMatrixEnable() { return true; }
10 | public boolean isDumpHprof() { return false;}
11 |
12 | @Override
13 | public String get(String key, String defStr) {
14 | //hook to change default values
15 | return defStr;
16 | }
17 |
18 | @Override
19 | public int get(String key, int defInt) {
20 | //hook to change default values
21 | return defInt;
22 | }
23 |
24 | @Override
25 | public long get(String key, long defLong) {
26 | //hook to change default values
27 | // if (IDynamicConfig.ExptEnum.clicfg_matrix_trace_evil_method_threshold.name().equals(key)) {
28 | // return 300; // 默认为700
29 | // }
30 | return defLong;
31 | }
32 |
33 | @Override
34 | public boolean get(String key, boolean defBool) {
35 | //hook to change default values
36 | return defBool;
37 | }
38 |
39 | @Override
40 | public float get(String key, float defFloat) {
41 | //hook to change default values
42 | return defFloat;
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/apmlib/src/main/java/com/mikel/apmlib/MatrixManager.java:
--------------------------------------------------------------------------------
1 | package com.mikel.apmlib;
2 |
3 | import android.app.Application;
4 |
5 | import com.tencent.matrix.Matrix;
6 | //import com.tencent.matrix.iocanary.IOCanaryPlugin;
7 | //import com.tencent.matrix.iocanary.config.IOConfig;
8 | import com.tencent.matrix.trace.TracePlugin;
9 | import com.tencent.matrix.trace.config.TraceConfig;
10 |
11 | public class MatrixManager {
12 |
13 | private static volatile MatrixManager INSTANCE;
14 |
15 | private MatrixManager() {
16 | }
17 |
18 | public static MatrixManager getInstance() {
19 | if (INSTANCE == null) {
20 | synchronized (MatrixManager.class) {
21 | if (INSTANCE == null) {
22 | INSTANCE = new MatrixManager();
23 | }
24 | }
25 | }
26 | return INSTANCE;
27 | }
28 |
29 | public void doOnCreate(Application application, String splashActivity) {
30 | Matrix.Builder builder = new Matrix.Builder(application); // build matrix
31 | builder.pluginListener(new MatrixPluginListener(application)); // add general pluginListener
32 | MatrixDynamicConfigImpl matrixDynamicConfig = new MatrixDynamicConfigImpl(); // dynamic config
33 | boolean fpsEnable = matrixDynamicConfig.isFPSEnable();
34 | boolean traceEnable = matrixDynamicConfig.isTraceEnable();
35 | //Trace plugin
36 | TraceConfig traceConfig = new TraceConfig.Builder()
37 | .dynamicConfig(matrixDynamicConfig)
38 | .enableFPS(true)//帧率
39 | .enableEvilMethodTrace(true)//慢方法
40 | .enableAnrTrace(true)//anr
41 | .enableSignalAnrTrace(true)//signal quit 信号监听 ANR
42 | .enableIdleHandlerTrace(true)//idle handler 卡顿
43 | .enableTouchEventTrace(true)
44 | .enableStartup(traceEnable)//启动速度
45 | .splashActivities(splashActivity)//首页
46 | //debug模式
47 | .isDebug(true)
48 | //dev环境
49 | .isDevEnv(false)
50 | .build();
51 |
52 | TracePlugin tracePlugin = new TracePlugin(traceConfig);
53 | builder.plugin(tracePlugin);
54 |
55 | // io plugin
56 | // IOCanaryPlugin ioCanaryPlugin = new IOCanaryPlugin(new IOConfig.Builder()
57 | // .dynamicConfig(matrixDynamicConfig)
58 | // .build());
59 | // builder.plugin(ioCanaryPlugin);
60 |
61 | //init matrix
62 | Matrix.init(builder.build());
63 | tracePlugin.start();
64 | // ioCanaryPlugin.start();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/apmlib/src/main/java/com/mikel/apmlib/MatrixPluginListener.java:
--------------------------------------------------------------------------------
1 | package com.mikel.apmlib;
2 |
3 | import android.content.Context;
4 |
5 | import com.tencent.matrix.plugin.DefaultPluginListener;
6 | import com.tencent.matrix.report.Issue;
7 | import com.tencent.matrix.util.MatrixLog;
8 |
9 | public class MatrixPluginListener extends DefaultPluginListener {
10 | public static final String TAG = "MatrixPluginListener";
11 | public MatrixPluginListener(Context context) {
12 | super(context);
13 | }
14 |
15 | @Override
16 | public void onReportIssue(Issue issue) {
17 | super.onReportIssue(issue);
18 | //todo 处理性能监控数据
19 | MatrixLog.e(TAG, issue.toString());
20 | }
21 | }
--------------------------------------------------------------------------------
/apmlib/src/test/java/com/mikel/apmlib/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.mikel.apmlib;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 |
5 | //todo matrix
6 | apply plugin: 'com.tencent.matrix-plugin'
7 | matrix {
8 | trace {
9 | enable = true //if you don't want to use trace canary, set false
10 | baseMethodMapFile = "${project.buildDir}/matrix_output/Debug.methodmap"
11 | blackListFile = "${project.projectDir}/matrixTrace/blackMethodList.txt"
12 | }
13 | }
14 |
15 | android {
16 | compileSdkVersion 34
17 |
18 | defaultConfig {
19 | applicationId "com.mikel.projectdemo"
20 | minSdkVersion 21
21 | targetSdkVersion 34
22 | versionCode 1
23 | versionName "1.0"
24 |
25 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
26 | }
27 |
28 | buildTypes {
29 | debug {
30 | minifyEnabled false
31 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
32 | }
33 | release {
34 | minifyEnabled false
35 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
36 | }
37 | }
38 | compileOptions {
39 | sourceCompatibility JavaVersion.VERSION_1_8
40 | targetCompatibility JavaVersion.VERSION_1_8
41 | }
42 |
43 | /**
44 | * 使用databinding
45 | */
46 | buildFeatures {
47 | dataBinding = true
48 | }
49 |
50 | packagingOptions {
51 | pickFirst 'lib/armeabi-v7a/libc++_shared.so'
52 | pickFirst 'lib/arm64-v8a/libc++_shared.so'
53 | }
54 | }
55 |
56 | dependencies {
57 |
58 | implementation 'androidx.appcompat:appcompat:1.2.0'
59 | implementation 'com.google.android.material:material:1.2.1'
60 | implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
61 | testImplementation 'junit:junit:4.+'
62 | androidTestImplementation 'androidx.test.ext:junit:1.1.2'
63 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
64 | annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
65 | api project(':baselib')
66 | api project(':apmlib')
67 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/mikel/projectdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.mikel.projectdemo", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
20 |
21 |
22 |
23 |
24 |
25 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
38 |
39 |
41 |
42 |
43 |
45 |
46 |
47 |
48 |
50 |
51 |
52 |
53 |
56 |
57 |
58 |
59 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 | import androidx.fragment.app.Fragment;
5 | import androidx.viewpager.widget.ViewPager;
6 |
7 | import android.os.Bundle;
8 | import android.widget.LinearLayout;
9 |
10 | import com.mikel.projectdemo.uiframework.JetPackFragment;
11 | import com.mikel.projectdemo.uiframework.MainFragment;
12 | import com.mikel.projectdemo.uiframework.MainViewPagerAdapter;
13 | import com.mikel.projectdemo.uiframework.MediaFragment;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | public class MainActivity extends AppCompatActivity {
19 |
20 | private MainViewPagerAdapter mMainViewPagerAdapter;
21 | private ViewPager mViewPager;
22 | private LinearLayout mTabContainerLy;
23 |
24 |
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | setContentView(R.layout.activity_main);
30 | initUI();
31 | }
32 |
33 | private void initUI() {
34 | mViewPager = findViewById(R.id.view_pager);
35 | mTabContainerLy = findViewById(R.id.tab_container_ly);
36 | //adapter填充数据
37 | List fragments = new ArrayList<>();
38 | fragments.add(MainFragment.build());
39 | fragments.add(MediaFragment.build());
40 | fragments.add(JetPackFragment.build());
41 | int[] tabResArray = new int[]{R.layout.fragment_tab_main, R.layout.fragment_tab_media, R.layout.fragment_tab_jetpack};
42 | mMainViewPagerAdapter = new MainViewPagerAdapter(getSupportFragmentManager(), mViewPager, mTabContainerLy, tabResArray);
43 | mMainViewPagerAdapter.setFragmentList(fragments);
44 | }
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/apm/ApmAnrTestService.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.apm;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.IBinder;
6 |
7 | import androidx.annotation.Nullable;
8 |
9 | public class ApmAnrTestService extends Service {
10 | @Override
11 | public void onCreate() {
12 | super.onCreate();
13 | }
14 |
15 |
16 | @Override
17 | public int onStartCommand(Intent intent, int flags, int startId) {
18 | try {
19 | Thread.sleep(21000);
20 | } catch (Exception e) {
21 |
22 | }
23 | return super.onStartCommand(intent, flags, startId);
24 | }
25 |
26 | @Override
27 | public void onDestroy() {
28 | super.onDestroy();
29 | }
30 |
31 | @Nullable
32 | @Override
33 | public IBinder onBind(Intent intent) {
34 | return null;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/apm/ApmTouchEventTestActivity.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.apm;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.MotionEvent;
6 |
7 | import com.mikel.projectdemo.R;
8 |
9 | public class ApmTouchEventTestActivity extends Activity {
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_touch_event_test);
15 | }
16 |
17 | @Override
18 | public boolean dispatchTouchEvent(MotionEvent ev) {
19 | try {
20 | Thread.sleep(8000);
21 | } catch (Exception e) {
22 |
23 | }
24 | return super.dispatchTouchEvent(ev);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/application/AppRuntime.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.application;
2 |
3 | import android.app.Application;
4 | import android.os.Handler;
5 | import android.os.Looper;
6 | import android.util.Log;
7 |
8 | import java.lang.reflect.Method;
9 |
10 | public abstract class AppRuntime {
11 |
12 | protected static final String TAG = "AppRuntime";
13 | private Handler mHandler = new Handler(Looper.getMainLooper());
14 | protected BaseApplication mApplication;
15 | public AppRuntime(BaseApplication app) {
16 | mApplication = app;
17 | }
18 |
19 | public void initAppRuntime() {
20 |
21 | }
22 |
23 | public Handler getHandler() {
24 | return mHandler;
25 | }
26 |
27 | public Application getApplication() {
28 | return mApplication;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/application/AppRuntimeForMain.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.application;
2 |
3 | import android.util.Log;
4 |
5 | import com.mikel.apmlib.MatrixManager;
6 |
7 | public class AppRuntimeForMain extends AppRuntime{
8 | public AppRuntimeForMain(BaseApplication app) {
9 | super(app);
10 | }
11 |
12 | @Override
13 | public void initAppRuntime() {
14 | super.initAppRuntime();
15 | Log.d(TAG, " main process runtime init");
16 | //todo 主进程初始化需要做的事情
17 | MatrixManager.getInstance().doOnCreate(getApplication(),"com.mikel.projectdemo.MainActivity");
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/application/AppRuntimeForVideo.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.application;
2 |
3 | import android.util.Log;
4 |
5 | public class AppRuntimeForVideo extends AppRuntime {
6 |
7 | public AppRuntimeForVideo(BaseApplication app) {
8 | super(app);
9 | }
10 |
11 | @Override
12 | public void initAppRuntime() {
13 | super.initAppRuntime();
14 | Log.d(TAG, " video process runtime init");
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/application/AppRuntimeForWeb.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.application;
2 |
3 | import android.util.Log;
4 |
5 | public class AppRuntimeForWeb extends AppRuntime{
6 |
7 | public AppRuntimeForWeb(BaseApplication app) {
8 | super(app);
9 | }
10 |
11 | @Override
12 | public void initAppRuntime() {
13 | super.initAppRuntime();
14 | Log.d(TAG, " web process runtime init");
15 | //todo web 进程初始化需要做的事情
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/application/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.application;
2 |
3 | import android.app.ActivityManager;
4 | import android.app.Application;
5 | import android.content.Context;
6 |
7 | import com.mikel.baselib.utils.AppUtil;
8 |
9 | import java.util.List;
10 |
11 | public class BaseApplication extends Application {
12 | protected static BaseApplication sBaseApplication;
13 | protected AppRuntime appRuntime;
14 | protected String processName;
15 |
16 | /**
17 | * 进程名字
18 | */
19 | public final static String MAPP_PROCESS_NAME = "com.mikel.projectdemo";
20 | public final static String WEB_PROCESS_NAME = "com.mikel.projectdemo:web";
21 | public final static String VIDEO_PROCESS_NAME = "com.mikel.projectdemo:video";
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 | sBaseApplication = this;
26 | AppUtil.setApplicationContext(getApplicationContext());
27 | //创建不同的进程
28 | createAppRuntime();
29 | appRuntime.initAppRuntime();
30 | }
31 |
32 | protected void createAppRuntime() {
33 | String processName = getAppProcessName();
34 | if (WEB_PROCESS_NAME.equals(processName)) {//web进程
35 | appRuntime = new AppRuntimeForWeb(sBaseApplication);
36 | } else if(VIDEO_PROCESS_NAME.equals(processName)) {//视频进程
37 | appRuntime = new AppRuntimeForVideo(sBaseApplication);
38 | } else {//主进程
39 | appRuntime = new AppRuntimeForMain(sBaseApplication);
40 | }
41 | }
42 |
43 | public String getAppProcessName() {
44 | if (processName == null) {
45 | ActivityManager actMgr = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
46 | List appList = actMgr
47 | .getRunningAppProcesses();
48 | if (null != appList) {
49 | for (ActivityManager.RunningAppProcessInfo info : appList) {
50 | if (info.pid == android.os.Process.myPid()) {
51 | processName = info.processName;
52 | break;
53 | }
54 | }
55 | }
56 | if (processName == null) {
57 | processName = getApplicationInfo().processName;
58 | }
59 | if (processName == null) {
60 | processName = MAPP_PROCESS_NAME;
61 | }
62 | }
63 | return processName;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/db/dao/PoetryDao.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.db.dao;
2 |
3 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
4 | import java.util.List;
5 | import androidx.room.Dao;
6 | import androidx.room.Insert;
7 | import androidx.room.OnConflictStrategy;
8 | import androidx.room.Query;
9 |
10 |
11 | /**
12 | * Created by mikeluo on 2019/3/18.
13 | * 封装增删改查的数据库接口
14 | */
15 |
16 | @Dao // DAO接口
17 | public interface PoetryDao {
18 | /**
19 | * 查询所有
20 | * @return
21 | */
22 | @Query("SELECT * FROM poetry_table")
23 | List getAllPoetries();
24 |
25 | /**
26 | * 分页查询数据库
27 | * @param startId
28 | * @param size
29 | * @return
30 | */
31 | @Query("SELECT * FROM poetry_table LIMIT :startId, :size")
32 | List getSpecificPoetries(int startId, int size);
33 |
34 | @Query("SELECT * FROM poetry_table WHERE title = :name")
35 | Poetry getPoetryByName(String name);
36 |
37 | @Insert(onConflict = OnConflictStrategy.REPLACE)
38 | void insertAll(List poetries);
39 |
40 | @Insert(onConflict = OnConflictStrategy.REPLACE)
41 | void insert(Poetry poetry);
42 |
43 | @Query("DELETE FROM poetry_table")
44 | void deleteAll();
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/db/dao/RemoteKeyDao.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.db.dao;
2 |
3 | import com.mikel.projectdemo.jetpack.service.model.RemoteKey;
4 |
5 | import androidx.room.Dao;
6 | import androidx.room.Insert;
7 | import androidx.room.OnConflictStrategy;
8 | import androidx.room.Query;
9 | import io.reactivex.Single;
10 |
11 | @Dao
12 | public interface RemoteKeyDao {
13 |
14 | @Query("SELECT * FROM remote_key_table WHERE key_label = :label")
15 | RemoteKey getRemoteKey(int label);
16 |
17 | @Insert(onConflict = OnConflictStrategy.REPLACE)
18 | void insertRemoteKey(RemoteKey remoteKey);
19 |
20 | @Query("DELETE FROM remote_key_table WHERE key_label = :label")
21 | void deleteRemoteKey(int label);
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/db/database/AppDatabase.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.db.database;
2 | import android.content.Context;
3 |
4 | import com.mikel.projectdemo.jetpack.service.db.dao.PoetryDao;
5 | import com.mikel.projectdemo.jetpack.service.db.dao.RemoteKeyDao;
6 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
7 | import com.mikel.projectdemo.jetpack.service.model.RemoteKey;
8 |
9 | import androidx.room.Database;
10 | import androidx.room.Room;
11 | import androidx.room.RoomDatabase;
12 | import androidx.room.migration.Migration;
13 | import androidx.sqlite.db.SupportSQLiteDatabase;
14 |
15 | /**
16 | * Created by mikeluo on 2019/3/18.
17 | */
18 | @Database(entities = {Poetry.class, RemoteKey.class}, version = 1, exportSchema = false) // 声明版本号1
19 | public abstract class AppDatabase extends RoomDatabase {
20 | private static AppDatabase INSTANCE;
21 | public abstract PoetryDao poetryDao();
22 | public abstract RemoteKeyDao remoteKeyDao();
23 |
24 | public static AppDatabase getInstance(Context context) {
25 | if(INSTANCE == null) {//单例设计模式 双重校验
26 | synchronized (AppDatabase.class) {
27 | if(INSTANCE == null) {
28 | INSTANCE = Room.databaseBuilder(context.getApplicationContext(),AppDatabase.class,
29 | "mikel_room.db").
30 | addMigrations(AppDatabase.MIGRATION_1_2).// 修改数据库字段时更新数据库
31 | allowMainThreadQueries().//允许在主线程读取数据库
32 | build();
33 | }
34 | }
35 | }
36 | return INSTANCE;
37 | }
38 |
39 | /**
40 | * 数据库变动添加Migration
41 | */
42 | public static final Migration MIGRATION_1_2 = new Migration(1, 2) {
43 | @Override
44 | public void migrate(SupportSQLiteDatabase database) {
45 | // todo 如果有修改数据库的字段 可以使用database.execSQL() 同时 修改数据库的version
46 | }
47 | };
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/model/Poetry.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.model;
2 |
3 | /**
4 | * Created by mikeluo on 2019/3/16.
5 | */
6 |
7 | import androidx.annotation.NonNull;
8 | import androidx.room.ColumnInfo;
9 | import androidx.room.Entity;
10 | import androidx.room.PrimaryKey;
11 |
12 | /**
13 | * 实体类—唐诗
14 | */
15 | @Entity(tableName = "poetry_table") //数据库表名poetry_table
16 | public class Poetry {
17 | @NonNull
18 | @ColumnInfo
19 | @PrimaryKey(autoGenerate = true) //主键
20 | public int poetry_id;
21 | @NonNull
22 | @ColumnInfo
23 | public String title; //标题
24 | @NonNull
25 | @ColumnInfo //列
26 | public String content; //内容
27 | @NonNull
28 | @ColumnInfo //列
29 | public String authors; // 作者
30 |
31 | public Poetry() {
32 | }
33 |
34 | @Override
35 | public String toString() {
36 | return "Poetry:" +
37 | "id=" + poetry_id +
38 | "title =" + title +
39 | ", content =" + content +
40 | ", author =" + authors;
41 | }
42 |
43 | public int getPoetry_id() {
44 | return poetry_id;
45 | }
46 |
47 | public void setPoetry_id(int poetry_id) {
48 | this.poetry_id = poetry_id;
49 | }
50 |
51 | @NonNull
52 | public String getTitle() {
53 | return title;
54 | }
55 |
56 | public void setTitle(@NonNull String title) {
57 | this.title = title;
58 | }
59 |
60 | @NonNull
61 | public String getContent() {
62 | return content;
63 | }
64 |
65 | public void setContent(@NonNull String content) {
66 | this.content = content;
67 | }
68 |
69 | @NonNull
70 | public String getAuthors() {
71 | return authors;
72 | }
73 |
74 | public void setAuthors(@NonNull String authors) {
75 | this.authors = authors;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/model/RemoteKey.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.model;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.room.ColumnInfo;
5 | import androidx.room.Entity;
6 | import androidx.room.PrimaryKey;
7 |
8 | @Entity(tableName = "remote_key_table")
9 | public class RemoteKey {
10 | @NonNull
11 | @ColumnInfo
12 | @PrimaryKey(autoGenerate = true) //主键
13 | private int key_label;//页码标识,代表具体哪个分页
14 |
15 | @ColumnInfo
16 | private String page_key;//下一次请求的分页页码
17 |
18 | public RemoteKey() {
19 | }
20 |
21 | public RemoteKey(int label, String page) {
22 | this.key_label = label;
23 | this.page_key = page;
24 | }
25 |
26 | @Override
27 | public String toString() {
28 | return "RemoteKey:" +
29 | "label =" + key_label +
30 | "page =" + page_key;
31 | }
32 |
33 | @NonNull
34 | public int getKey_label() {
35 | return key_label;
36 | }
37 |
38 | public void setKey_label(@NonNull int key_label) {
39 | this.key_label = key_label;
40 | }
41 |
42 |
43 | public String getPage_key() {
44 | return page_key;
45 | }
46 |
47 | public void setPage_key( String next_page) {
48 | this.page_key = next_page;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/model/Result.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.model;
2 |
3 | /**
4 | * Created by mikeluo on 2019/3/17.
5 | */
6 |
7 | /**
8 | * 字段的定义 需要遵循 Json串
9 | * 例子:
10 | *
11 | * {"code":200,
12 | * "message":"成功!",
13 | * result":{"title":"读张忠献公谥册感叹",
14 | * "content":"恩视韩兼赵,名均献与忠。|礼中非不极,勋外若为同。|三圣无多学,千年仅一翁。|犹怜公议在,拼泪乞秋风。
15 | * " ,"authors":"杨万里"}}
16 | * @param
17 | */
18 | public class Result {
19 | private int code;
20 | private String message;
21 | private Poetry result;
22 |
23 | public int getCode() {
24 | return code;
25 | }
26 |
27 | public String getMessage() {
28 | return message;
29 | }
30 |
31 | public Poetry getData() {
32 | return result;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/model/ResultList.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.model;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by mikeluo on 2019/3/17.
7 | * 字段的定义 需要遵循 Json串
8 | * 例子:
9 | *
10 | * {"code":200,
11 | * "message":"成功!",
12 | * "result":[{"title":"帝京篇十首 一","content":"秦川雄帝宅,函谷壮皇居。|绮殿千寻起,离宫百雉余。|连甍遥接汉,飞观迥凌虚。|云日隐层阙,风烟出绮疏。","authors":"太宗皇帝"},
13 | * {"title":"帝京篇十首 二","content":"岩廊罢机务,崇文聊驻辇。|玉匣启龙图,金绳披凤篆。|韦编断仍续,缥帙舒还卷。|对此乃淹留,欹案观坟典。","authors":"太宗皇帝"},
14 | * {"title":"帝京篇十首 三","content":"移步出词林,停舆欣武宴。|雕弓写明月,骏马疑流电。|惊雁落虚弦,啼猿悲急箭。|阅赏诚多美,于兹乃忘倦。","authors":"太宗皇帝"}]}
15 | */
16 |
17 | public class ResultList {
18 | private int code;
19 | private String message;
20 | private List result;
21 |
22 | public List getData() {
23 | return result;
24 | }
25 |
26 | public int getCode() {
27 | return code;
28 | }
29 |
30 | public void setCode(int code) {
31 | this.code = code;
32 | }
33 |
34 | public String getMessage() {
35 | return message;
36 | }
37 |
38 | public void setMessage(String message) {
39 | this.message = message;
40 | }
41 |
42 | public List getResult() {
43 | return result;
44 | }
45 |
46 | public void setResult(List result) {
47 | this.result = result;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/network/CustomLoggingInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.network;
2 |
3 | import android.util.Log;
4 |
5 | import com.mikel.projectdemo.jetpack.service.utils.Constants;
6 |
7 | import java.io.IOException;
8 | import java.nio.charset.Charset;
9 | import java.nio.charset.UnsupportedCharsetException;
10 | import java.util.concurrent.TimeUnit;
11 | import okhttp3.Interceptor;
12 | import okhttp3.MediaType;
13 | import okhttp3.Request;
14 | import okhttp3.RequestBody;
15 | import okhttp3.Response;
16 | import okhttp3.ResponseBody;
17 | import okio.Buffer;
18 | import okio.BufferedSource;
19 |
20 | /**
21 | * Created by mikeluo on 2019/3/17.
22 | */
23 |
24 | public class CustomLoggingInterceptor implements Interceptor {
25 | private final Charset UTF8 = Charset.forName("UTF-8");
26 |
27 | @Override
28 | public Response intercept(Chain chain) throws IOException {
29 |
30 | Request request = chain.request();
31 | RequestBody requestBody = request.body();
32 |
33 | String body = null;
34 |
35 | if(requestBody != null) {
36 | Buffer buffer = new Buffer();
37 | requestBody.writeTo(buffer);
38 |
39 | Charset charset = UTF8;
40 | MediaType contentType = requestBody.contentType();
41 | if (contentType != null) {
42 | charset = contentType.charset(UTF8);
43 | }
44 | body = buffer.readString(charset);
45 | }
46 |
47 | Log.i(Constants.TAG,String.format("发送请求\nmethod:%s\nurl:%s\nheaders: %sbody:%s",
48 | request.method(), request.url(), request.headers(), body));
49 |
50 | long startNs = System.nanoTime();
51 | Response response = chain.proceed(request);
52 | long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
53 |
54 | ResponseBody responseBody = response.body();
55 | String rBody = null;
56 |
57 |
58 | if(responseBody != null) {
59 | BufferedSource source = responseBody.source();
60 | source.request(Long.MAX_VALUE); // Buffer the entire body.
61 | Buffer buffer = source.buffer();
62 |
63 | Charset charset = UTF8;
64 | MediaType contentType = responseBody.contentType();
65 | if (contentType != null) {
66 | try {
67 | charset = contentType.charset(UTF8);
68 | } catch (UnsupportedCharsetException e) {
69 | e.printStackTrace();
70 | }
71 | }
72 | rBody = buffer.clone().readString(charset);
73 | }
74 |
75 | Log.i(Constants.TAG,String.format("收到响应 %s%s %ss\n请求url:%s\n请求body:%s\n响应body:%s",
76 | response.code(), response.message(), tookMs, response.request().url(), body, rBody));
77 |
78 | return response;
79 | }
80 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/network/PagingNetWorkApiService.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.network;
2 | //lib添加retrofit2.jar包
3 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
4 | import com.mikel.projectdemo.jetpack.service.model.ResultList;
5 |
6 | import androidx.paging.RemoteMediator;
7 | import io.reactivex.Observable;
8 | import io.reactivex.Single;
9 | import retrofit2.http.GET;
10 | import retrofit2.http.Query;
11 |
12 |
13 | /**
14 | * Created by mikeluo on 2019/3/16.
15 | */
16 |
17 | public interface PagingNetWorkApiService {
18 | public static String HTTPS_API_OPEN_URL = "https://api.apiopen.top/";
19 |
20 | //获取唐诗列表Rxjava
21 | @GET("getTangPoetry")
22 | Observable> fetchPoetryListForRxJava(@Query("page") String page, @Query("count") String count);
23 |
24 |
25 | @GET("getTangPoetry")
26 | Single> fetchPoetryListForPaging3(@Query("page") String page, @Query("count") String count);
27 |
28 | //根据名称搜索唐诗
29 | @GET("searchPoetry")
30 | Observable> searchPoetry(@Query("name") String name);
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/paging2/LocalPageKeyedDataSource.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.paging2;
2 |
3 | import android.util.Log;
4 |
5 | import com.mikel.projectdemo.jetpack.service.db.dao.PoetryDao;
6 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
7 | import com.mikel.projectdemo.jetpack.service.utils.Constants;
8 | import com.mikel.projectdemo.jetpack.service.utils.Utils;
9 |
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | import java.util.List;
13 |
14 | import androidx.annotation.NonNull;
15 | import androidx.paging.PageKeyedDataSource;
16 |
17 | /**
18 | * 适用于根据页请求数据的场景
19 | */
20 | public class LocalPageKeyedDataSource extends PageKeyedDataSource {
21 | public static final int PAGE_SIZE = 3;
22 | private PoetryDao mPoetryDao;
23 | public LocalPageKeyedDataSource(PoetryDao poetryDao) {
24 | mPoetryDao = poetryDao;
25 | }
26 |
27 | @Override
28 | public void loadInitial(@NonNull @NotNull LoadInitialParams params, @NonNull @NotNull LoadInitialCallback callback) {
29 | /**
30 | * 初始化只从数据库查首页 pageKey = 0, 下一页pageKey = 1
31 | */
32 | List firstPageList = mPoetryDao.getSpecificPoetries(0, PAGE_SIZE);
33 | Log.w(Constants.TAG, " load initial ");
34 | Utils.printPoetryInfo(firstPageList);
35 | callback.onResult(firstPageList, null, 1);
36 | }
37 |
38 | @Override
39 | public void loadBefore(@NonNull @NotNull LoadParams params, @NonNull @NotNull LoadCallback callback) {
40 | Log.w(Constants.TAG, " load before param key = " + params.key);
41 | }
42 |
43 | @Override
44 | public void loadAfter(@NonNull @NotNull LoadParams params, @NonNull @NotNull LoadCallback callback) {
45 | int startID = params.key * params.requestedLoadSize;
46 | Log.w(Constants.TAG, " load after start id = " + startID + " size= " + params.requestedLoadSize);
47 | /**
48 | * 每次只从数据库里 查一页数据
49 | */
50 | List dataList = mPoetryDao.getSpecificPoetries(startID, params.requestedLoadSize);
51 | Utils.printPoetryInfo(dataList);
52 | if (dataList != null) {
53 | callback.onResult(dataList, params.key + 1);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/paging2/LocalPageKeyedDataSourceFactory.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.paging2;
2 |
3 | import com.mikel.projectdemo.jetpack.service.db.dao.PoetryDao;
4 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
5 |
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.paging.DataSource;
10 |
11 | public class LocalPageKeyedDataSourceFactory extends DataSource.Factory {
12 | private PoetryDao mPoetryDao;
13 | private DataSource mDataSource;
14 | public LocalPageKeyedDataSourceFactory(PoetryDao poetryDao) {
15 | mPoetryDao = poetryDao;
16 | }
17 | @NonNull
18 | @NotNull
19 | @Override
20 | public DataSource create() {
21 | mDataSource = new LocalPageKeyedDataSource(mPoetryDao);
22 | return mDataSource;
23 | }
24 |
25 | public DataSource getDataSource() {
26 | return mDataSource;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/paging2/NetPagedKeyedDataSourceFactory.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.paging2;
2 | import android.content.Context;
3 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
4 |
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | import androidx.annotation.NonNull;
8 | import androidx.paging.DataSource;
9 |
10 | public class NetPagedKeyedDataSourceFactory extends DataSource.Factory {
11 | private Context mContext;
12 |
13 | NetPagedKeyedDataSource mNetPagedKeyedDataSource;
14 | public NetPagedKeyedDataSourceFactory(Context context) {
15 | this.mContext = context;
16 | }
17 |
18 | @NonNull
19 | @NotNull
20 | @Override
21 | public DataSource create() {
22 | mNetPagedKeyedDataSource = new NetPagedKeyedDataSource(mContext);
23 | return mNetPagedKeyedDataSource;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/paging3/PoetryListPagingSource.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.paging3;
2 |
3 | import android.util.Log;
4 |
5 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
6 | import com.mikel.projectdemo.jetpack.service.model.ResultList;
7 | import com.mikel.projectdemo.jetpack.service.network.PagingNetWorkApiService;
8 | import com.mikel.projectdemo.jetpack.service.repository.RepositoryManager;
9 | import com.mikel.projectdemo.jetpack.service.utils.Constants;
10 |
11 | import org.jetbrains.annotations.NotNull;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | import androidx.annotation.NonNull;
18 | import androidx.paging.PagingState;
19 | import androidx.paging.rxjava2.RxPagingSource;
20 | import io.reactivex.Single;
21 | public class PoetryListPagingSource extends RxPagingSource {
22 | @NonNull
23 | private PagingNetWorkApiService mPagingNetWorkApiService;
24 | private int nextPageKey = 0;
25 | public PoetryListPagingSource(@NonNull PagingNetWorkApiService pagingNetWorkApiService) {
26 | mPagingNetWorkApiService = pagingNetWorkApiService;
27 | }
28 |
29 | @NotNull
30 | @Override
31 | public Single> loadSingle(
32 | @NotNull LoadParams params) {
33 | Integer nextPageNumber = params.getKey();
34 | if (nextPageNumber == null) {
35 | nextPageNumber = 0;
36 | }
37 |
38 | nextPageKey = nextPageNumber;
39 |
40 | Log.d(Constants.TAG, "Paging3框架,PagingSource loadSingle call, page = " + nextPageKey);
41 |
42 | /**
43 | * todo
44 | * 由于网络接口失效,这里构建测试数据 模拟服务端的返回,
45 | * 正常情况下直接使用下面被注释掉的代码mPagingNetWorkApiService.fetchPoetryListForPaging3
46 | */
47 | // return mPagingNetWorkApiService.fetchPoetryListForPaging3(String.valueOf(nextPageKey),
48 | // String.valueOf(Constants.PAGING_PAGE_SIZE))
49 | // .subscribeOn(Schedulers.io())
50 | // .map(this::toLoadResult)
51 | // .onErrorReturn(LoadResult.Error::new);
52 | ResultList testResultList = buildTestResultList(String.valueOf(nextPageKey));
53 | return Single.just(toLoadResult(testResultList));
54 | }
55 |
56 | private LoadResult toLoadResult(
57 | @NonNull ResultList resultList) {
58 | return new LoadResult.Page<>(
59 | resultList.getData(),
60 | null, // Only paging forward.
61 | nextPageKey + 1,
62 | LoadResult.Page.COUNT_UNDEFINED,
63 | LoadResult.Page.COUNT_UNDEFINED);
64 | }
65 |
66 | @Nullable
67 | @Override
68 | public Integer getRefreshKey(@NotNull PagingState state) {
69 | Integer anchorPosition = state.getAnchorPosition();
70 | if (anchorPosition == null) {
71 | return null;
72 | }
73 |
74 | LoadResult.Page anchorPage = state.closestPageToPosition(anchorPosition);
75 | if (anchorPage == null) {
76 | return null;
77 | }
78 |
79 | Integer prevKey = anchorPage.getPrevKey();
80 | if (prevKey != null) {
81 | return prevKey + 1;
82 | }
83 |
84 | Integer nextKey = anchorPage.getNextKey();
85 | if (nextKey != null) {
86 | return nextKey - 1;
87 | }
88 |
89 | return null;
90 | }
91 |
92 | /**
93 | * 模拟服务端返回,构造分页测试数据
94 | * @param page
95 | * @return
96 | */
97 | private ResultList buildTestResultList(String page) {
98 | ResultList resultList = new ResultList<>();
99 | List poetries = new ArrayList<>();
100 | for(int i=0; i<3; i++){
101 | long time = System.currentTimeMillis() + i;
102 | Poetry poetry = new Poetry();
103 | poetry.poetry_id = (int)time;
104 | poetry.title = "NetworkResponse_第" + page + "页_第" + i
105 | +"条数据_" + RepositoryManager.CACHE_TITLE[i] + "_" + time;
106 | poetry.content= RepositoryManager.CACHE_CONTENT[i];
107 | poetry.authors= RepositoryManager.CACHE_AUTHOR[i];
108 | poetries.add(poetry);
109 | }
110 | resultList.setCode(200);
111 | resultList.setMessage("Test Data Success");
112 | resultList.setResult(poetries);
113 | return resultList;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/utils/Constants.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.utils;
2 |
3 | /**
4 | * Created by mikeluo on 2019/3/17.
5 | */
6 |
7 | public class Constants {
8 | public final static String TAG = "ViewModel_LiveData_MVVM";
9 |
10 | public final static int PAGING_PAGE_SIZE = 3;
11 | public final static int PAGING_FIRST_PAGE = 0;
12 | public final static int PAGING_REMOTE_KEY_LABEL_PORTRY = 0;
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/service/utils/Utils.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.service.utils;
2 |
3 | import android.util.Log;
4 |
5 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
6 |
7 | import java.util.List;
8 |
9 |
10 | /**
11 | * Created by mikeluo on 2019/3/19.
12 | */
13 |
14 | public class Utils {
15 |
16 | public static void printMsg(String msg) {
17 | Log.i(Constants.TAG, msg);
18 | }
19 | public static void printPoetryInfo(List poetries) {
20 | if (poetries == null || poetries.size() == 0) {
21 | Log.i(Constants.TAG, " poetry list is empty");
22 | return;
23 | }
24 |
25 | for (int i = 0; i
19 | */
20 | public class PoetryListAdapterForPaging2 extends PagedListAdapter {
21 |
22 | private final PoetryClickCallBack mPoetryClickCallback;
23 |
24 | public PoetryListAdapterForPaging2(PoetryClickCallBack poetryClickCallBack) {
25 | super(new DiffUtil.ItemCallback() {
26 |
27 | @Override
28 | public boolean areItemsTheSame(@NonNull Poetry oldItem, @NonNull Poetry newItem) {
29 | return oldItem.title.equals(newItem.title);
30 | }
31 |
32 | @Override
33 | public boolean areContentsTheSame(@NonNull Poetry oldItem, @NonNull Poetry newItem) {
34 | return oldItem.title.equals(newItem.title)
35 | && oldItem.content.equals(newItem.content)
36 | && oldItem.authors.equals(newItem.authors);
37 | }
38 | });
39 | this.mPoetryClickCallback = poetryClickCallBack;
40 | }
41 |
42 | @Override
43 | public PoetryListAdapterForPaging2.PoetryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
44 | //databind框架自动生成PoetryListItemBinding
45 | PoetryListItemBinding binding = DataBindingUtil
46 | .inflate(LayoutInflater.from(parent.getContext()), R.layout.poetry_list_item,
47 | parent, false);
48 |
49 | binding.setCallback(mPoetryClickCallback);// 双向绑定;自动生成一个setXXX方法
50 | return new PoetryListAdapterForPaging2.PoetryViewHolder(binding);
51 | }
52 |
53 | @Override
54 | public void onBindViewHolder(PoetryListAdapterForPaging2.PoetryViewHolder holder, int position) {
55 | Poetry poetry = getItem(position);
56 | holder.binding.setPoetry(poetry);
57 | holder.binding.executePendingBindings();
58 | }
59 |
60 | /**
61 | * holder类
62 | */
63 | static class PoetryViewHolder extends RecyclerView.ViewHolder {
64 |
65 | final PoetryListItemBinding binding;
66 |
67 | public PoetryViewHolder(PoetryListItemBinding binding) {
68 | super(binding.getRoot());
69 | this.binding = binding;
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/view/adapter/PoetryListAdapterForPaging3.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.view.adapter;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.ViewGroup;
5 |
6 | import com.mikel.projectdemo.R;
7 | import com.mikel.projectdemo.databinding.PoetryListItemBinding;
8 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
9 | import com.mikel.projectdemo.jetpack.view.callback.PoetryClickCallBack;
10 |
11 | import org.jetbrains.annotations.NotNull;
12 |
13 | import androidx.annotation.NonNull;
14 | import androidx.databinding.DataBindingUtil;
15 | import androidx.paging.PagingDataAdapter;
16 | import androidx.recyclerview.widget.DiffUtil;
17 | import androidx.recyclerview.widget.RecyclerView;
18 |
19 | public class PoetryListAdapterForPaging3 extends PagingDataAdapter {
20 |
21 | private final PoetryClickCallBack mPoetryClickCallback;
22 |
23 | public PoetryListAdapterForPaging3(PoetryClickCallBack poetryClickCallBack) {
24 | super(new DiffUtil.ItemCallback() {
25 |
26 | @Override
27 | public boolean areItemsTheSame(@NonNull Poetry oldItem, @NonNull Poetry newItem) {
28 | return oldItem.title.equals(newItem.title);
29 | }
30 |
31 | @Override
32 | public boolean areContentsTheSame(@NonNull Poetry oldItem, @NonNull Poetry newItem) {
33 | return oldItem.title.equals(newItem.title)
34 | && oldItem.content.equals(newItem.content)
35 | && oldItem.authors.equals(newItem.authors);
36 | }
37 | });
38 | this.mPoetryClickCallback = poetryClickCallBack;
39 | }
40 |
41 | @NonNull
42 | @NotNull
43 | @Override
44 | public PoetryViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
45 | //databind框架自动生成PoetryListItemBinding
46 | PoetryListItemBinding binding = DataBindingUtil
47 | .inflate(LayoutInflater.from(parent.getContext()), R.layout.poetry_list_item,
48 | parent, false);
49 |
50 | binding.setCallback(mPoetryClickCallback);// 双向绑定;自动生成一个setXXX方法
51 | return new PoetryListAdapterForPaging3.PoetryViewHolder(binding);
52 | }
53 |
54 | @Override
55 | public void onBindViewHolder(@NonNull @NotNull PoetryViewHolder holder, int position) {
56 | Poetry poetry = getItem(position);
57 | holder.binding.setPoetry(poetry);
58 | holder.binding.executePendingBindings();
59 | }
60 |
61 | /**
62 | * holder类
63 | */
64 | static class PoetryViewHolder extends RecyclerView.ViewHolder {
65 |
66 | final PoetryListItemBinding binding;
67 |
68 | public PoetryViewHolder(PoetryListItemBinding binding) {
69 | super(binding.getRoot());
70 | this.binding = binding;
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/view/callback/PoetryClickCallBack.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.view.callback;
2 |
3 |
4 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
5 |
6 | /**
7 | * Created by mikeluo on 2019/3/18.
8 | */
9 |
10 | public interface PoetryClickCallBack {
11 | void onClick(Poetry poetry);
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/view/ui/Paging3MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.view.ui;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 |
6 | import com.mikel.projectdemo.R;
7 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
8 |
9 | import androidx.appcompat.app.AppCompatActivity;
10 |
11 | public class Paging3MainActivity extends AppCompatActivity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_paging3_main);
17 |
18 | if (savedInstanceState == null) {
19 | PoetryListFragmentForPaging3 fragment = new PoetryListFragmentForPaging3();
20 | getSupportFragmentManager().beginTransaction()
21 | .add(R.id.fragment_container, fragment, PoetryListFragmentForPaging3.TAG).commit();
22 | }
23 | }
24 |
25 |
26 | /**
27 | * 点击具体某个item跳转
28 | * @param poetry
29 | */
30 | public void show(Poetry poetry) {
31 | Intent intent = new Intent(this, PoetryDetailActivity.class);
32 | intent.putExtra("title", poetry.title);
33 | startActivity(intent);
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/view/ui/PoetryDetailActivity.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.view.ui;
2 |
3 | import android.os.Bundle;
4 |
5 | import com.mikel.projectdemo.R;
6 |
7 | import androidx.appcompat.app.AppCompatActivity;
8 |
9 |
10 | /**
11 | * Created by mikeluo on 2019/3/19.
12 | */
13 |
14 | public class PoetryDetailActivity extends AppCompatActivity {
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.activity_detail_poetry);
19 |
20 | if (savedInstanceState == null) {
21 | PoetryFragment poetryFragment = PoetryFragment.forPoetry(getIntent().getStringExtra("title"));
22 | getSupportFragmentManager().beginTransaction()
23 | .add(R.id.fragment_container, poetryFragment, PoetryListFragmentForPaging2Local.TAG).commit();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/view/ui/PoetryFragment.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.view.ui;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import com.mikel.projectdemo.R;
9 | import com.mikel.projectdemo.databinding.FragmentPoetryDetailBinding;
10 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
11 | import com.mikel.projectdemo.jetpack.service.utils.Utils;
12 | import com.mikel.projectdemo.jetpack.viewmodel.PoetryViewModel;
13 |
14 | import androidx.databinding.DataBindingUtil;
15 | import androidx.fragment.app.Fragment;
16 | import androidx.lifecycle.Observer;
17 |
18 | /**
19 | * Created by mikeluo on 2019/3/17.
20 | * * 1. Fragment,Activity这些content应该要持有adapter, binding, ViewModel
21 | * 2. ViewModel里面应该要提供一个接口 setDataInfo:对viewModel里面的observerField成员变量进行赋值—同步数据到UI
22 | * 3. 对于2的 setDataInfo接口什么时候调用呢?
23 | * 场景1:在onCreate时加载本地缓存或者DB拿到本地数据。 场景2:网络拉取—回包拿到数据后需要一个观察者模式通知UI
24 | * 4. 对于场景2的观察者模式—该demo采用了liveData,liveData.setValue方法调用后,内部会触发Observer.onChanged方法
25 | * 接着在onChanted方法里面 调用viewModel.setDataInfo() —— dataBinding的作用会同步到UI
26 | */
27 |
28 |
29 | public class PoetryFragment extends Fragment {
30 | public static final String TAG = "PoetryFragment";
31 | private static final String KEY_POETRY_ID = "poetry_id";
32 | //框架自动生成FragmentPoetryDetailBinding
33 | private FragmentPoetryDetailBinding mFragmentPoetryDetailBinding;
34 | private PoetryViewModel mPoetryViewModel;
35 |
36 | @Override
37 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
38 | mFragmentPoetryDetailBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_poetry_detail, container, false);
39 | return mFragmentPoetryDetailBinding.getRoot();
40 | }
41 |
42 | @Override
43 | public void onActivityCreated( Bundle savedInstanceState) {
44 | super.onActivityCreated(savedInstanceState);
45 | PoetryViewModel.Factory factory = new PoetryViewModel.Factory(
46 | getActivity().getApplication(), getArguments().getString(KEY_POETRY_ID));
47 | mPoetryViewModel = new PoetryViewModel(this.getActivity().getApplication(),
48 | getArguments().getString(KEY_POETRY_ID));
49 | mFragmentPoetryDetailBinding.setIsLoading(true);
50 | //先读本地
51 | mPoetryViewModel.loadDataInfo(getArguments().getString(KEY_POETRY_ID));
52 | observeViewModelLocal(mPoetryViewModel);
53 |
54 | //todo 由于网络接口失效, 先注释掉网络请求。
55 | // mPoetryViewModel.requestSearchPoetry(getArguments().getString(KEY_POETRY_ID));
56 | // observeViewModelNetwork(mPoetryViewModel);
57 | }
58 |
59 | /**
60 | * LiveData被观察者和观察者activty ,fragment建立订阅关系
61 | * @param viewModel
62 | */
63 | private void observeViewModelNetwork(final PoetryViewModel viewModel) {
64 | viewModel.getmPoetryObservableNetwork().observe(this, new Observer() {
65 | @Override
66 | public void onChanged(Poetry poetry) {
67 | Utils.printPoetryInfo(poetry);//打日志
68 | if (poetry != null) {
69 | mFragmentPoetryDetailBinding.setIsLoading(false);// binding调用setXXX方法后,数据同步到UI
70 | mFragmentPoetryDetailBinding.setPoetry(poetry);// binding调用setXXX方法后,数据同步到UI
71 | }
72 | }
73 | });
74 | }
75 |
76 | private void observeViewModelLocal(final PoetryViewModel viewModel) {
77 | viewModel.getmPoetryObservableLocal().observe(this, new Observer() {
78 | @Override
79 | public void onChanged(Poetry poetry) {
80 | Utils.printPoetryInfo(poetry);//打日志
81 | if (poetry != null) {
82 | mFragmentPoetryDetailBinding.setIsLoading(false);// binding调用setXXX方法后,数据同步到UI
83 | mFragmentPoetryDetailBinding.setPoetry(poetry);// binding调用setXXX方法后,数据同步到UI
84 | }
85 | }
86 | });
87 | }
88 | /**
89 | * 根据poetryId创建一个PoetryFragment
90 | * @param poetryID
91 | * @return
92 | */
93 | public static PoetryFragment forPoetry(String poetryID) {
94 | PoetryFragment fragment = new PoetryFragment();
95 | Bundle args = new Bundle();
96 |
97 | args.putString(KEY_POETRY_ID, poetryID);
98 | fragment.setArguments(args);
99 |
100 | return fragment;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/view/ui/PoetryListFragmentForPaging2Local.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.view.ui;
2 |
3 | import android.os.Bundle;
4 | import android.util.Log;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.mikel.projectdemo.R;
10 | import com.mikel.projectdemo.databinding.FragmentPoetryListBinding;
11 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
12 | import com.mikel.projectdemo.jetpack.service.repository.RepositoryManager;
13 | import com.mikel.projectdemo.jetpack.service.utils.Constants;
14 | import com.mikel.projectdemo.jetpack.service.utils.Utils;
15 | import com.mikel.projectdemo.jetpack.view.adapter.PoetryListAdapterForPaging2;
16 | import com.mikel.projectdemo.jetpack.view.callback.PoetryClickCallBack;
17 | import com.mikel.projectdemo.jetpack.viewmodel.PoetryListViewModelForPaging2Local;
18 |
19 | import androidx.annotation.Nullable;
20 | import androidx.databinding.DataBindingUtil;
21 | import androidx.fragment.app.Fragment;
22 | import androidx.lifecycle.Lifecycle;
23 | import androidx.lifecycle.Observer;
24 | import androidx.paging.PagedList;
25 |
26 | /**
27 | * Created by mikeluo on 2019/3/17.
28 | */
29 |
30 | public class PoetryListFragmentForPaging2Local extends Fragment {
31 |
32 | public static final String TAG = "PoetryListFragmentForPaging2";
33 | //分页PagedListAdapter
34 | private PoetryListAdapterForPaging2 mCustomPagedPoetryAdapter;
35 | private FragmentPoetryListBinding mFragmentPoetryListBinding;
36 | private PoetryListViewModelForPaging2Local mPoetryListViewModelForPaging2Local;
37 | @Override
38 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
39 | @Nullable Bundle savedInstanceState) {
40 | mFragmentPoetryListBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_poetry_list, container, false);
41 | mCustomPagedPoetryAdapter = new PoetryListAdapterForPaging2(mPoetryClickCallBack);
42 | //mFragmentPoetryListBinding.poetryList根据layout xml的id
43 | mFragmentPoetryListBinding.poetryList.setAdapter(mCustomPagedPoetryAdapter);
44 | mFragmentPoetryListBinding.setIsLoading(true);
45 | return mFragmentPoetryListBinding.getRoot();
46 | }
47 |
48 | @Override
49 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
50 | super.onActivityCreated(savedInstanceState);
51 | //构建本地数据
52 | RepositoryManager.getInstance().buildLocalTestData(getContext());
53 |
54 | //1. 初始化viewModel
55 | mPoetryListViewModelForPaging2Local = new PoetryListViewModelForPaging2Local(this.getActivity().getApplication());
56 | //2.注册本地监听
57 | registerViewModelLocal();
58 | }
59 |
60 | /**
61 | * 读取DB 或者 缓存观察者回调监听
62 | */
63 | private void registerViewModelLocal() {
64 | Log.d(Constants.TAG, "注册本地监听");
65 | //分页模式
66 | mPoetryListViewModelForPaging2Local.getLocalLiveDataPageListPoetry().observe(this, new Observer>() {
67 | @Override
68 | public void onChanged(final PagedList poetries) {
69 | Utils.printMsg(" -----------------local paging onChanged----------------");
70 | Utils.printPoetryInfo( poetries);
71 | mFragmentPoetryListBinding.setIsLoading(false);//去掉loading
72 | mCustomPagedPoetryAdapter.submitList(poetries);
73 | }
74 | });
75 | }
76 |
77 | private PoetryClickCallBack mPoetryClickCallBack = new PoetryClickCallBack() {
78 | @Override
79 | public void onClick(Poetry poetry) {
80 | if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
81 | ((Paging2MainActivity) getActivity()).show(poetry);
82 | }
83 | }
84 | };
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/view/ui/PoetryListFragmentForPaging2Network.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.view.ui;
2 |
3 | import android.os.Bundle;
4 | import android.util.Log;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.mikel.projectdemo.R;
10 | import com.mikel.projectdemo.databinding.FragmentPoetryListBinding;
11 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
12 | import com.mikel.projectdemo.jetpack.service.utils.Constants;
13 | import com.mikel.projectdemo.jetpack.service.utils.Utils;
14 | import com.mikel.projectdemo.jetpack.view.adapter.PoetryListAdapterForPaging2;
15 | import com.mikel.projectdemo.jetpack.view.callback.PoetryClickCallBack;
16 | import com.mikel.projectdemo.jetpack.viewmodel.PoetryListViewModelForPaging2Network;
17 |
18 | import androidx.annotation.Nullable;
19 | import androidx.databinding.DataBindingUtil;
20 | import androidx.fragment.app.Fragment;
21 | import androidx.lifecycle.Lifecycle;
22 | import androidx.lifecycle.Observer;
23 | import androidx.paging.PagedList;
24 |
25 | /**
26 | * Created by mikeluo on 2019/3/17.
27 | */
28 |
29 | public class PoetryListFragmentForPaging2Network extends Fragment {
30 |
31 | public static final String TAG = "PoetryListFragmentForPaging2";
32 | //分页PagedListAdapter
33 | private PoetryListAdapterForPaging2 mCustomPagedPoetryAdapter;
34 | private FragmentPoetryListBinding mFragmentPoetryListBinding;
35 | private PoetryListViewModelForPaging2Network mPoetryListViewModelForPaging2Network;
36 | @Override
37 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
38 | @Nullable Bundle savedInstanceState) {
39 | mFragmentPoetryListBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_poetry_list, container, false);
40 | mCustomPagedPoetryAdapter = new PoetryListAdapterForPaging2(mPoetryClickCallBack);
41 | //mFragmentPoetryListBinding.poetryList根据layout xml的id
42 | mFragmentPoetryListBinding.poetryList.setAdapter(mCustomPagedPoetryAdapter);
43 | mFragmentPoetryListBinding.setIsLoading(true);
44 | return mFragmentPoetryListBinding.getRoot();
45 | }
46 |
47 | @Override
48 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
49 | super.onActivityCreated(savedInstanceState);
50 | //1. 初始化viewModel
51 | mPoetryListViewModelForPaging2Network = new PoetryListViewModelForPaging2Network(this.getActivity().getApplication());
52 | //2. 注册网络监听
53 | registerViewModelNetwork();
54 | }
55 |
56 | /**
57 | * 网络拉取的观察者回调监听
58 | */
59 | private void registerViewModelNetwork() {
60 | Log.d(Constants.TAG, "注册网络监听");
61 | mPoetryListViewModelForPaging2Network.getNetLiveDataPageListPoetry().observe(this, new Observer>() {
62 | @Override
63 | public void onChanged(PagedList poetries) {
64 | Utils.printMsg(" -----------------network paging onChanged----------------");
65 | Utils.printPoetryInfo( poetries);
66 | mFragmentPoetryListBinding.setIsLoading(false);
67 | mCustomPagedPoetryAdapter.submitList(poetries);
68 | }
69 | });
70 | }
71 |
72 | private PoetryClickCallBack mPoetryClickCallBack = new PoetryClickCallBack() {
73 | @Override
74 | public void onClick(Poetry poetry) {
75 | if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
76 | ((Paging2MainActivity) getActivity()).show(poetry);
77 | }
78 | }
79 | };
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/view/ui/PoetryListFragmentForPaging3.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.view.ui;
2 |
3 | import android.os.Bundle;
4 | import android.util.Log;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.mikel.projectdemo.R;
10 | import com.mikel.projectdemo.databinding.FragmentPoetryListBinding;
11 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
12 | import com.mikel.projectdemo.jetpack.service.utils.Constants;
13 | import com.mikel.projectdemo.jetpack.view.adapter.PoetryListAdapterForPaging3;
14 | import com.mikel.projectdemo.jetpack.view.callback.PoetryClickCallBack;
15 | import com.mikel.projectdemo.jetpack.viewmodel.PoetryListViewModelForPaging3;
16 |
17 | import androidx.annotation.Nullable;
18 | import androidx.databinding.DataBindingUtil;
19 | import androidx.fragment.app.Fragment;
20 | import androidx.lifecycle.Lifecycle;
21 |
22 |
23 | public class PoetryListFragmentForPaging3 extends Fragment {
24 |
25 | public static final String TAG = "PoetryListFragmentForPaging3";
26 | //分页PagedListAdapter
27 | private PoetryListAdapterForPaging3 mCustomPagedPoetryAdapter;
28 | private FragmentPoetryListBinding mFragmentPoetryListBinding;
29 | private PoetryListViewModelForPaging3 mPoetryListViewModelForPaging3;
30 | @Override
31 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
32 | @Nullable Bundle savedInstanceState) {
33 | mFragmentPoetryListBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_poetry_list, container, false);
34 | mCustomPagedPoetryAdapter = new PoetryListAdapterForPaging3(mPoetryClickCallBack);
35 | //mFragmentPoetryListBinding.poetryList根据layout xml的id
36 | mFragmentPoetryListBinding.poetryList.setAdapter(mCustomPagedPoetryAdapter);
37 | mFragmentPoetryListBinding.setIsLoading(true);
38 | return mFragmentPoetryListBinding.getRoot();
39 | }
40 |
41 | @Override
42 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
43 | super.onActivityCreated(savedInstanceState);
44 | //1. 初始化viewModel
45 | mPoetryListViewModelForPaging3 = new PoetryListViewModelForPaging3(getContext());
46 | //2. viewmodel 获取 obserable ,注册数据监听
47 | subscribePagingData();
48 | }
49 |
50 | private void subscribePagingData() {
51 | mPoetryListViewModelForPaging3.getPoetryObservable().subscribe(poetryPagingData -> {
52 | Log.d(Constants.TAG, " paging3 observe data changed");
53 | mFragmentPoetryListBinding.setIsLoading(false);//去掉loading
54 | mCustomPagedPoetryAdapter.submitData(getLifecycle(), poetryPagingData);
55 | });
56 | }
57 |
58 |
59 | private PoetryClickCallBack mPoetryClickCallBack = new PoetryClickCallBack() {
60 | @Override
61 | public void onClick(Poetry poetry) {
62 | if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
63 | ((Paging3MainActivity) getActivity()).show(poetry);
64 | }
65 | }
66 | };
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/viewmodel/PoetryListViewModelForPaging2Local.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.viewmodel;
2 |
3 | import android.app.Application;
4 |
5 | import com.mikel.projectdemo.jetpack.service.db.dao.PoetryDao;
6 | import com.mikel.projectdemo.jetpack.service.db.database.AppDatabase;
7 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
8 | import com.mikel.projectdemo.jetpack.service.paging2.LocalPageKeyedDataSource;
9 | import com.mikel.projectdemo.jetpack.service.paging2.LocalPageKeyedDataSourceFactory;
10 | import androidx.lifecycle.AndroidViewModel;
11 | import androidx.lifecycle.LiveData;
12 | import androidx.paging.LivePagedListBuilder;
13 | import androidx.paging.PagedList;
14 |
15 | /**
16 | * Created by mikeluo on 2019/3/17.
17 | */
18 |
19 | public class PoetryListViewModelForPaging2Local extends AndroidViewModel {
20 | PoetryDao mPortryDao;
21 | private LiveData> localLiveDataPageListPoetry;
22 | private LocalPageKeyedDataSourceFactory mLocalPageKeyedDataSourceFactory;
23 | public PoetryListViewModelForPaging2Local(Application application) {
24 | super(application);
25 |
26 | mPortryDao = AppDatabase.getInstance(this.getApplication()).poetryDao();
27 | //本地数据源
28 | mLocalPageKeyedDataSourceFactory = new LocalPageKeyedDataSourceFactory(mPortryDao);
29 | localLiveDataPageListPoetry = new LivePagedListBuilder<>(mLocalPageKeyedDataSourceFactory,
30 | LocalPageKeyedDataSource.PAGE_SIZE).build();
31 | }
32 |
33 | public LiveData> getLocalLiveDataPageListPoetry() {
34 | return localLiveDataPageListPoetry;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/viewmodel/PoetryListViewModelForPaging2Network.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.viewmodel;
2 |
3 | import android.app.Application;
4 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
5 | import com.mikel.projectdemo.jetpack.service.paging2.LocalPageKeyedDataSource;
6 | import com.mikel.projectdemo.jetpack.service.paging2.NetPagedKeyedDataSourceFactory;
7 | import androidx.lifecycle.AndroidViewModel;
8 | import androidx.lifecycle.LiveData;
9 | import androidx.paging.LivePagedListBuilder;
10 | import androidx.paging.PagedList;
11 |
12 | /**
13 | * Created by mikeluo on 2019/3/17.
14 | */
15 |
16 | public class PoetryListViewModelForPaging2Network extends AndroidViewModel {
17 | private LiveData> netLiveDataPageListPoetry;
18 | private NetPagedKeyedDataSourceFactory mNetPagedKeyedDataSourceFactory;
19 | public PoetryListViewModelForPaging2Network(Application application) {
20 | super(application);
21 | //网络数据源
22 | mNetPagedKeyedDataSourceFactory = new NetPagedKeyedDataSourceFactory(getApplication());
23 | netLiveDataPageListPoetry = new LivePagedListBuilder<>(mNetPagedKeyedDataSourceFactory,
24 | LocalPageKeyedDataSource.PAGE_SIZE).build();
25 | }
26 | public LiveData> getNetLiveDataPageListPoetry() {
27 | return netLiveDataPageListPoetry;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/viewmodel/PoetryListViewModelForPaging3.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.viewmodel;
2 | import android.content.Context;
3 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
4 | import com.mikel.projectdemo.jetpack.service.network.RetrofitManager;
5 | import com.mikel.projectdemo.jetpack.service.paging3.PoetryListPagingSource;
6 | import com.mikel.projectdemo.jetpack.service.utils.Constants;
7 | import androidx.lifecycle.ViewModel;
8 | import androidx.lifecycle.ViewModelKt;
9 | import androidx.paging.Pager;
10 | import androidx.paging.PagingConfig;
11 | import androidx.paging.PagingData;
12 | import androidx.paging.rxjava2.PagingRx;
13 | import io.reactivex.Observable;
14 | import kotlinx.coroutines.CoroutineScope;
15 |
16 | /**
17 | * paging3 viewmodel
18 | */
19 | public class PoetryListViewModelForPaging3 extends ViewModel {
20 | Pager mPager;
21 | PoetryListPagingSource mPoetryListPagingSource;
22 |
23 | //rxjava observable
24 | Observable> mPoetryObservable;
25 | public PoetryListViewModelForPaging3(Context context) {
26 | CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(this);
27 | /**
28 | * 数据源
29 | */
30 | mPoetryListPagingSource = new PoetryListPagingSource(RetrofitManager.getInstance(context).getPagingNetWorkApiService());
31 | /**
32 | * Pager :分页大管家, 使用网络数据源构造
33 | */
34 | mPager = new Pager(new PagingConfig(Constants.PAGING_PAGE_SIZE), () -> mPoetryListPagingSource);
35 |
36 | /**
37 | * PagingRx.getObservable
38 | */
39 | mPoetryObservable = PagingRx.getObservable(mPager);
40 | PagingRx.cachedIn(mPoetryObservable, viewModelScope);
41 | }
42 |
43 | public Observable> getPoetryObservable() {
44 | return mPoetryObservable;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/jetpack/viewmodel/PoetryViewModel.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.jetpack.viewmodel;
2 |
3 | import android.app.Application;
4 |
5 | import com.mikel.projectdemo.jetpack.service.db.database.AppDatabase;
6 | import com.mikel.projectdemo.jetpack.service.model.Poetry;
7 | import com.mikel.projectdemo.jetpack.service.network.RetrofitManager;
8 | import com.mikel.projectdemo.jetpack.service.utils.Utils;
9 |
10 | import androidx.lifecycle.AndroidViewModel;
11 | import androidx.lifecycle.LiveData;
12 | import androidx.lifecycle.MutableLiveData;
13 | import androidx.lifecycle.ViewModel;
14 | import androidx.lifecycle.ViewModelProvider;
15 |
16 |
17 | /**
18 | * Created by mikeluo on 2019/3/17.
19 | */
20 |
21 | public class PoetryViewModel extends AndroidViewModel {
22 |
23 | /**
24 | * 使用同一个obserable监听 只会响应最后的一个
25 | * 这里区分本地的和network的
26 | */
27 | // MutableLiveData继承liveData, 提供了setValue和postValue方法。liveData 是抽象类
28 | private MutableLiveData mPoetryObservableLocal= new MutableLiveData<>();
29 | private MutableLiveData mPoetryObservableNetwork = new MutableLiveData<>();
30 | private final String poetryID;
31 |
32 | public PoetryViewModel(Application application, String poetryID) {
33 | super(application);
34 | this.poetryID = poetryID;
35 | }
36 |
37 | /**
38 | * 读DB或者缓存
39 | * 根据具体的名字获取Poetry
40 | */
41 | public Poetry loadDataInfo(String name) {
42 | Utils.printMsg(" poetry detail load info");
43 | Poetry poetry = AppDatabase.getInstance(this.getApplication()).poetryDao().getPoetryByName(name);
44 | mPoetryObservableLocal.setValue(poetry);// setValue 需要在主进程调用
45 | return poetry;
46 | }
47 |
48 | /**
49 | * 发送网络请求
50 | * 真实的请求逻辑封装到了RetrofitManager
51 | * 根据名称搜索某个poetry
52 | * @param name
53 | */
54 | public void requestSearchPoetry(String name) {
55 | mPoetryObservableNetwork = RetrofitManager.getInstance(this.getApplication()).searchPoetry(name);
56 | }
57 |
58 | /**
59 | * 返回LiveData 对象
60 | * @return
61 | */
62 | public LiveData getmPoetryObservableNetwork() {
63 | return mPoetryObservableNetwork;
64 | }
65 |
66 | public LiveData getmPoetryObservableLocal() {
67 | return mPoetryObservableLocal;
68 | }
69 |
70 | public static class Factory extends ViewModelProvider.NewInstanceFactory {
71 | private final Application application;
72 |
73 | private final String poetryID;
74 |
75 | public Factory( Application application, String poetryID) {
76 | this.application = application;
77 | this.poetryID = poetryID;
78 | }
79 |
80 | @Override
81 | public T create(Class modelClass) {
82 | //noinspection unchecked
83 | return (T) new PoetryViewModel(application, poetryID);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/media/video/VideoFileNameGenerator.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.media.video;
2 |
3 | import android.net.Uri;
4 |
5 | import com.danikula.videocache.ProxyCacheUtils;
6 | import com.danikula.videocache.file.FileNameGenerator;
7 |
8 | public class VideoFileNameGenerator implements FileNameGenerator {
9 |
10 | @Override
11 | public String generate(String url) {
12 | Uri uri = Uri.parse(url);
13 | String path = uri.getHost() + uri.getPath();
14 | return ProxyCacheUtils.computeMD5(path);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/media/video/VideoPlayTask.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.media.video;
2 |
3 |
4 | //import com.google.android.exoplayer2.ui.PlayerView;
5 |
6 | import androidx.media3.ui.PlayerView;
7 |
8 | public class VideoPlayTask {
9 | private PlayerView mSimpleExoPlayerView;
10 | private String mVideoUrl;
11 |
12 | public VideoPlayTask(PlayerView simpleExoPlayerView, String uri) {
13 | this.mSimpleExoPlayerView = simpleExoPlayerView;
14 | this.mVideoUrl = uri;
15 | }
16 |
17 | public PlayerView getSimpleExoPlayerView() {
18 | return mSimpleExoPlayerView;
19 | }
20 |
21 | public void setSimpleExoPlayerView(PlayerView mSimpleExoPlayerView) {
22 | this.mSimpleExoPlayerView = mSimpleExoPlayerView;
23 | }
24 |
25 | public String getVideoUrl() {
26 | return mVideoUrl;
27 | }
28 |
29 | public void setVideoUrl(String videoUrl) {
30 | this.mVideoUrl = videoUrl;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/media/video/VideoViewPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.media.video;
2 | import androidx.media3.ui.PlayerView;
3 | import androidx.recyclerview.widget.RecyclerView;
4 | import android.content.Context;
5 | import android.util.Log;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | //import com.google.android.exoplayer2.ui.PlayerView;
11 | import com.mikel.projectdemo.R;
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | import androidx.annotation.NonNull;
16 |
17 |
18 | public class VideoViewPagerAdapter extends RecyclerView.Adapter {
19 | private Context mContext;
20 | private List mVieoUrls = new ArrayList<>();
21 |
22 |
23 | public VideoViewPagerAdapter(Context context) {
24 | super();
25 | this.mContext = context;
26 | }
27 |
28 | public void setDataList(List videoUrls) {
29 | mVieoUrls.clear();
30 | mVieoUrls.addAll(videoUrls);
31 | notifyDataSetChanged();
32 | Log.d("Video_Play_TAG", "setDataList" );
33 | }
34 |
35 | public void addDataList(List videoUrls) {
36 | mVieoUrls.addAll(videoUrls);
37 | notifyDataSetChanged();
38 | }
39 |
40 | @NonNull
41 | @Override
42 | public VideoViewPagerAdapter.VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
43 | View itemView = LayoutInflater.from(mContext).inflate(R.layout.fragment_video_item, parent, false);
44 | return new VideoViewHolder(itemView);
45 | }
46 |
47 | @Override
48 | public void onBindViewHolder(@NonNull VideoViewPagerAdapter.VideoViewHolder holder, int position) {
49 | holder.videoUrl = mVieoUrls.get(position);
50 | holder.itemView.setTag(position);
51 | Log.d("Video_Play_TAG", " on bind view holder pos = "+ position + " , url = " + holder.videoUrl);
52 | }
53 |
54 | @Override
55 | public int getItemCount() {
56 | return mVieoUrls.size();
57 | }
58 |
59 | public class VideoViewHolder extends RecyclerView.ViewHolder {
60 | public PlayerView mVideoView;
61 | public String videoUrl;
62 |
63 | VideoViewHolder(View itemView) {
64 | super(itemView);
65 | mVideoView = itemView.findViewById(R.id.play_view);
66 | }
67 | }
68 |
69 | public String getUrlByPos(int pos) {
70 | return mVieoUrls.get(pos);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/uiframework/JetPackFragment.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.uiframework;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.mikel.projectdemo.R;
10 | import com.mikel.projectdemo.jetpack.view.ui.Paging2MainActivity;
11 | import com.mikel.projectdemo.jetpack.view.ui.Paging3MainActivity;
12 |
13 | import org.jetbrains.annotations.NotNull;
14 |
15 | import androidx.annotation.NonNull;
16 | import androidx.annotation.Nullable;
17 | import androidx.fragment.app.Fragment;
18 |
19 | public class JetPackFragment extends Fragment {
20 |
21 | public static JetPackFragment build() {
22 | return new JetPackFragment();
23 | }
24 |
25 | @Override
26 | public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
27 | View jetPackRootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_jetpack_main, null, true);
28 |
29 | jetPackRootView.findViewById(R.id.paging2_main_btn).setOnClickListener(new View.OnClickListener() {
30 | @Override
31 | public void onClick(View v) {
32 | Intent intent = new Intent(getActivity(), Paging2MainActivity.class);
33 | startActivity(intent);
34 | }
35 | });
36 |
37 | jetPackRootView.findViewById(R.id.paging3_main_btn).setOnClickListener(new View.OnClickListener() {
38 | @Override
39 | public void onClick(View v) {
40 | Intent intent = new Intent(getActivity(), Paging3MainActivity.class);
41 | startActivity(intent);
42 | }
43 | });
44 |
45 | return jetPackRootView;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/uiframework/MainFragment.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.uiframework;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.LinearLayout;
8 |
9 | import com.mikel.projectdemo.R;
10 | import com.mikel.projectdemo.uiframework.subtab.SubTabFragment1;
11 | import com.mikel.projectdemo.uiframework.subtab.SubTabFragment2;
12 | import com.mikel.projectdemo.uiframework.subtab.SubTabFragment3;
13 |
14 | import org.jetbrains.annotations.NotNull;
15 |
16 | import java.util.ArrayList;
17 | import java.util.List;
18 |
19 | import androidx.annotation.NonNull;
20 | import androidx.annotation.Nullable;
21 | import androidx.fragment.app.Fragment;
22 | import androidx.viewpager.widget.ViewPager;
23 |
24 | public class MainFragment extends Fragment {
25 |
26 | private TabSubViewPagerAdapter mTabSubViewPagerAdapter;
27 | private ViewPager mViewPager;
28 | private LinearLayout mTabContainerLy;
29 |
30 |
31 | public static MainFragment build() {
32 | return new MainFragment();
33 | }
34 |
35 | @Override
36 | public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
37 | View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_main, null, true);
38 | mViewPager = rootView.findViewById(R.id.view_pager);
39 | mTabContainerLy = rootView.findViewById(R.id.tab_container_ly);
40 | //adapter填充数据
41 | List fragments = new ArrayList<>();
42 | fragments.add(SubTabFragment1.build());
43 | fragments.add(SubTabFragment2.build());
44 | fragments.add(SubTabFragment3.build());
45 | int[] tabResArray = new int[]{R.layout.fragment_sub_tab_title1, R.layout.fragment_sub_tab_title2, R.layout.fragment_sub_tab_title3};
46 | mTabSubViewPagerAdapter = new TabSubViewPagerAdapter(getChildFragmentManager(), mViewPager, mTabContainerLy, tabResArray);
47 | mTabSubViewPagerAdapter.setFragmentList(fragments);
48 | return rootView;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/uiframework/MainViewPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.uiframework;
2 | import android.view.View;
3 | import android.widget.LinearLayout;
4 | import android.widget.TextView;
5 |
6 | import com.mikel.projectdemo.R;
7 |
8 | import androidx.fragment.app.FragmentManager;
9 | import androidx.viewpager.widget.ViewPager;
10 |
11 | /**
12 | * MainActivity ViewPager的 Adapter
13 | */
14 | public class MainViewPagerAdapter extends BaseViewPagerAdapter {
15 | public MainViewPagerAdapter(FragmentManager fragmentManager, ViewPager viewPager, LinearLayout tabContainer, int[] tabResArray) {
16 | super(fragmentManager, viewPager, tabContainer, tabResArray);
17 | }
18 |
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/uiframework/TabSubViewPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.uiframework;
2 |
3 |
4 | import android.view.View;
5 | import android.widget.LinearLayout;
6 | import android.widget.TextView;
7 |
8 | import com.mikel.projectdemo.R;
9 |
10 | import androidx.fragment.app.FragmentManager;
11 | import androidx.viewpager.widget.ViewPager;
12 |
13 | public class TabSubViewPagerAdapter extends BaseViewPagerAdapter {
14 | public TabSubViewPagerAdapter(FragmentManager fragmentManager, ViewPager viewPager, LinearLayout tabContainer, int[] tabResArray) {
15 | super(fragmentManager, viewPager, tabContainer, tabResArray);
16 | }
17 |
18 |
19 | @Override
20 | protected int getTabViewHeightDp() {
21 | return 30;
22 | }
23 |
24 | /**
25 | * 更新tab ui
26 | * @param position
27 | */
28 | @Override
29 | public void updateTabViewUI(int position) {
30 | for(int i =0; i < mTabViews.size(); i++) {
31 | View tabView = mTabViews.get(i);
32 | TextView tabTitleView = tabView.findViewById(R.id.tab_title);
33 | if(i == position) {
34 | tabTitleView.setTextColor(tabTitleView.getResources().getColor(R.color.white));
35 | } else {
36 | tabTitleView.setTextColor(tabTitleView.getResources().getColor(R.color.medium_green));
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/uiframework/VideoTestFragment.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.uiframework;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.Nullable;
11 | import androidx.fragment.app.Fragment;
12 | import androidx.media3.common.MediaItem;
13 | import androidx.media3.exoplayer.ExoPlayer;
14 | //import androidx.media3.exoplayer.SimpleExoPlayer;
15 | import androidx.media3.ui.PlayerView;
16 |
17 | import com.mikel.projectdemo.R;
18 | import org.jetbrains.annotations.NotNull;
19 |
20 |
21 | public class VideoTestFragment extends Fragment {
22 | public static VideoTestFragment build() {
23 | return new VideoTestFragment();
24 | }
25 |
26 | private Context mContext;
27 | private ExoPlayer mSimpleExoPlayer;
28 | private PlayerView playerView;
29 |
30 | @Override
31 | public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
32 | mContext = getActivity();
33 | View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_video_item, null, true);
34 | initUI(rootView);
35 | return rootView;
36 | }
37 |
38 | private void initUI(View rootView) {
39 | mSimpleExoPlayer = new ExoPlayer.Builder(getActivity()).build();
40 | // 准备要播放的媒体资源
41 | MediaItem mediaItem = MediaItem.fromUri("https://vfx.mtime.cn/Video/2019/01/15/mp4/190115161611510728_480.mp4");
42 | mSimpleExoPlayer.setMediaItem(mediaItem);
43 | // 将ExoPlayer关联到要显示视频的View
44 | playerView = rootView.findViewById(R.id.play_view);
45 | //绑定player和playerView
46 | playerView.setPlayer(mSimpleExoPlayer);
47 | mSimpleExoPlayer.setPlayWhenReady(true);
48 | startPlay();
49 | }
50 |
51 | public void startPlay() {
52 | // 准备播放器
53 | mSimpleExoPlayer.prepare();
54 | mSimpleExoPlayer.play();
55 | }
56 |
57 | /**
58 | * 停止播放
59 | */
60 | public void stopPlay() {
61 | pausePlay();
62 | if(mSimpleExoPlayer != null) {
63 | mSimpleExoPlayer.release();
64 | mSimpleExoPlayer = null;
65 | }
66 | }
67 |
68 | public void resumePlay() {
69 | if(mSimpleExoPlayer != null) {
70 | mSimpleExoPlayer.setPlayWhenReady(true);
71 | } else {
72 | startPlay();
73 | }
74 | }
75 |
76 | public void pausePlay() {
77 | if(mSimpleExoPlayer != null) {
78 | mSimpleExoPlayer.setPlayWhenReady(false);
79 | }
80 | }
81 |
82 |
83 | @Override
84 | public void onDestroyView() {
85 | super.onDestroyView();
86 | stopPlay();
87 | }
88 |
89 | @Override
90 | public void onResume() {
91 | super.onResume();
92 | resumePlay();
93 | }
94 |
95 | @Override
96 | public void onStop() {
97 | super.onStop();
98 | pausePlay();
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/uiframework/subtab/SubTabFragment2.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.uiframework.subtab;
2 |
3 | import android.animation.AnimatorSet;
4 | import android.animation.ObjectAnimator;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.webkit.WebChromeClient;
10 | import android.webkit.WebSettings;
11 | import android.webkit.WebView;
12 | import android.widget.Button;
13 | import android.widget.FrameLayout;
14 |
15 | import com.mikel.projectdemo.R;
16 |
17 | import org.jetbrains.annotations.NotNull;
18 |
19 | import androidx.annotation.NonNull;
20 | import androidx.annotation.Nullable;
21 | import androidx.fragment.app.Fragment;
22 |
23 | public class SubTabFragment2 extends Fragment {
24 | public static SubTabFragment2 build() {
25 | return new SubTabFragment2();
26 | }
27 |
28 | @Override
29 | public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
30 | View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_sub_tab_content2, null, true);
31 | initUI(rootView);
32 | return rootView;
33 | }
34 |
35 | private void initUI(View rootView) {
36 | Button webTestBtn = rootView.findViewById(R.id.test_webview_btn);
37 | FrameLayout webFrameLayout = rootView.findViewById(R.id.webview_layout);
38 | WebView webView = new WebView(webFrameLayout.getContext());
39 | WebSettings webSettings = webView.getSettings();
40 | webSettings.setJavaScriptEnabled(true);
41 | webSettings.setSupportZoom(false);
42 | webSettings.setUseWideViewPort(true);
43 | webSettings.setLoadWithOverviewMode(true);
44 | webSettings.setDefaultTextEncodingName("utf-8");
45 | webSettings.setLoadsImagesAutomatically(true);
46 | webView.loadUrl("https://www.baidu.com");
47 | webTestBtn.setOnClickListener(new View.OnClickListener() {
48 | @Override
49 | public void onClick(View v) {
50 | //动态添加WebView
51 | webFrameLayout.removeAllViews();
52 | webFrameLayout.addView(webView);
53 | final AnimatorSet animatorSet = new AnimatorSet();
54 | //缩放动画+淡入淡出动画
55 | animatorSet.playTogether(ObjectAnimator.ofFloat(webView, "scaleX", 0, 1)
56 | .setDuration(1000),ObjectAnimator.ofFloat(webView, "scaleY", 0, 1)
57 | .setDuration(1000), ObjectAnimator.ofFloat(webView, "alpha", 0, 1)
58 | .setDuration(1000));
59 | //动画开始的原点
60 | webView.setPivotX(webFrameLayout.getWidth() - 20);
61 | webView.setPivotY(30);
62 | animatorSet.start();
63 | }
64 | });
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/uiframework/subtab/SubTabFragment3.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.uiframework.subtab;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.Button;
8 | import android.widget.Toast;
9 |
10 | import com.mikel.nativelib.JNIHelper;
11 | import com.mikel.projectdemo.R;
12 |
13 | import org.jetbrains.annotations.NotNull;
14 |
15 | import androidx.annotation.NonNull;
16 | import androidx.annotation.Nullable;
17 | import androidx.fragment.app.Fragment;
18 |
19 | public class SubTabFragment3 extends Fragment {
20 |
21 | public static SubTabFragment3 build() {
22 | return new SubTabFragment3();
23 | }
24 |
25 | @Override
26 | public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
27 | View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_sub_tab_content3, null, true);
28 | initUI(rootView);
29 | return rootView;
30 | }
31 |
32 | private void initUI(View rootView) {
33 | Button testJNIBtn = rootView.findViewById(R.id.testJNIBtn);
34 | testJNIBtn.setOnClickListener(new View.OnClickListener() {
35 | @Override
36 | public void onClick(View v) {
37 | StringBuilder result = new StringBuilder();
38 | String temp = JNIHelper.testJNI();
39 | result.append(temp).append("\n");
40 | result.append("需要加密的字符串:").append("123456789").append("\n");
41 | String encodeStr = JNIHelper.encryptJNI("123456789");
42 | result.append("加密后字符串:").append(encodeStr).append("\n");
43 | String decodeStr = JNIHelper.decryptJNI(encodeStr);
44 | result.append("解密后字符串:").append(decodeStr).append("\n");
45 |
46 |
47 | int[] iArray = {1,2,3};
48 | float[] fArray = {4f,5f,6f};
49 | double[] dArray = {7.01,8.02, 9.03};
50 | byte[] bArray = {0x10, 0x11};
51 | boolean[] booleans = {true, true, false};
52 | String ret = JNIHelper.dynamicMethodTest(1,2, 3, (byte) 4,"5", true, iArray, fArray, dArray, bArray, booleans);
53 | result.append("动态注册返回:").append(ret);
54 | Toast.makeText(getContext(), result.toString(), Toast.LENGTH_LONG).show();
55 | }
56 | });
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/utils/CPUUtil.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.utils;
2 |
3 | import android.util.Log;
4 |
5 | import java.io.RandomAccessFile;
6 |
7 | public class CPUUtil {
8 |
9 | private static final String TAG = "CPUUtil";
10 | public static double getProcessCpuRate(int processId) {
11 | long start = System.currentTimeMillis();
12 | long cpuTime = 0L;
13 | long appTime = 0L;
14 | double cpuRate = 0.0D;
15 | RandomAccessFile procStatFile = null;
16 | RandomAccessFile appStatFile = null;
17 |
18 | try {
19 | procStatFile = new RandomAccessFile("/proc/stat", "r");
20 | String procStatString = procStatFile.readLine();
21 | String[] procStats = procStatString.split(" ");
22 | cpuTime = Long.parseLong(procStats[2]) + Long.parseLong(procStats[3])
23 | + Long.parseLong(procStats[4]) + Long.parseLong(procStats[5])
24 | + Long.parseLong(procStats[6]) + Long.parseLong(procStats[7])
25 | + Long.parseLong(procStats[8]);
26 |
27 | } catch (Exception e) {
28 | Log.i(TAG, "RandomAccessFile(Process Stat) reader fail, error: e =" + e.toString());
29 | } finally {
30 | try {
31 | if (null != procStatFile) {
32 | procStatFile.close();
33 | }
34 |
35 | } catch (Exception e) {
36 | Log.i(TAG, "close process reader e =" + e.toString());
37 | }
38 | }
39 |
40 | try {
41 | appStatFile = new RandomAccessFile("/proc/" + processId + "/stat", "r");
42 | String appStatString = appStatFile.readLine();
43 | String[] appStats = appStatString.split(" ");
44 | appTime = Long.parseLong(appStats[13]) + Long.parseLong(appStats[14]);
45 | } catch (Exception e) {
46 | Log.i(TAG, "RandomAccessFile(App Stat) reader fail, error: " + e.toString());
47 | } finally {
48 | try {
49 | if (null != appStatFile) {
50 | appStatFile.close();
51 | }
52 | } catch (Exception e) {
53 | Log.i(TAG, "close app reader " + e.toString());
54 | }
55 | }
56 |
57 | if (0 != cpuTime) {
58 | cpuRate = ((double) (appTime) / (double) (cpuTime)) * 100D;
59 | }
60 |
61 | Log.i(TAG, "getAppCpuRate cost:" + (System.currentTimeMillis() - start) + ",rate:" + cpuRate);
62 | return cpuRate;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/utils/FileHelper.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.utils;
2 |
3 | import android.content.ContentResolver;
4 | import android.content.Context;
5 | import android.net.Uri;
6 | import android.util.Log;
7 |
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.FileOutputStream;
11 | import java.io.InputStream;
12 | import java.io.OutputStream;
13 |
14 | public class FileHelper {
15 | public static final String TAG = "FileUtil_TAG";
16 | /**
17 | * 通过uri拷贝外部存储的文件到自己应用的沙盒目录
18 | * @param uri 外部存储文件的uri
19 | * @param destFile 沙盒文件陆军
20 | */
21 | public static void copyFieUriToInnerStorage(Context context, Uri uri, File destFile) {
22 | InputStream inputStream = null;
23 | FileOutputStream fileOutputStream = null;
24 | try {
25 | inputStream = context.getContentResolver().openInputStream(uri);
26 | if(destFile.exists()) {
27 | destFile.delete();
28 | }
29 | fileOutputStream = new FileOutputStream(destFile);
30 | byte[] buffer = new byte[4096];
31 | int redCount;
32 | while ((redCount = inputStream.read(buffer)) >= 0) {
33 | fileOutputStream.write(buffer, 0, redCount);
34 | }
35 | } catch (Exception e) {
36 | Log.e(TAG, " copy file uri to inner storage e = " + e.toString());
37 | } finally {
38 | try {
39 | if(fileOutputStream != null) {
40 | fileOutputStream.flush();
41 | fileOutputStream.getFD().sync();
42 | fileOutputStream.close();
43 | }
44 | if(inputStream != null) {
45 | inputStream.close();
46 | }
47 | } catch (Exception e) {
48 | Log.e(TAG, " close stream e = " + e.toString());
49 | }
50 | }
51 | }
52 |
53 | /**
54 | * 拷贝沙盒中的文件到外部存储区域
55 | * @param filePath 沙盒文件路径
56 | * @param externalUri 外部存储文件的 uri
57 | */
58 | public static boolean copySandFileToExternalUri(Context context, String filePath, Uri externalUri) {
59 | ContentResolver contentResolver = context.getContentResolver();
60 | InputStream inputStream = null;
61 | OutputStream outputStream = null;
62 | boolean ret = false;
63 | try {
64 | outputStream = contentResolver.openOutputStream(externalUri);
65 | File sandFile = new File(filePath);
66 | if(sandFile.exists()) {
67 | inputStream = new FileInputStream(sandFile);
68 |
69 | int readCount = 0;
70 | byte[] buffer = new byte[1024];
71 | while ((readCount = inputStream.read(buffer)) != -1) {
72 | outputStream.write(buffer, 0 , readCount);
73 | outputStream.flush();
74 | }
75 | }
76 | ret = true;
77 | } catch (Exception e) {
78 | Log.e(TAG, "copy SandFile To ExternalUri. e = " + e.toString());
79 | ret = false;
80 | } finally {
81 | try {
82 | if(outputStream != null) {
83 | outputStream.close();
84 | }
85 | if(inputStream != null) {
86 | inputStream.close();
87 | }
88 | Log.d(TAG, " input stream and output stream close successful.");
89 | } catch (Exception e) {
90 | e.printStackTrace();
91 | Log.e(TAG, " input stream and output stream close fail. e = " + e.toString());
92 | }
93 | return ret;
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/utils/MemoryUtil.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.utils;
2 |
3 | import android.text.TextUtils;
4 | import android.util.Log;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.FileInputStream;
8 | import java.io.InputStreamReader;
9 |
10 | public class MemoryUtil {
11 | public final static String TAG = "Memory_TAG";
12 | public static long getProcessRealMemory() {
13 | String memFilePath = "/proc/" + android.os.Process.myPid() + "/status";
14 | BufferedReader bufferedReader = null;
15 | try {
16 | FileInputStream fileInputStream = new FileInputStream(memFilePath);
17 | InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
18 | bufferedReader = new BufferedReader(inputStreamReader);
19 | String line;
20 | while ((line = bufferedReader.readLine()) != null) {
21 | Log.d(TAG, line);
22 | if(!TextUtils.isEmpty(line) && line.contains("VmRSS")) {
23 | String rss = line.split(":")[1].trim().split( " ")[0];
24 | return Integer.parseInt(rss) * 1024;
25 | }
26 | }
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | } finally {
30 | if(bufferedReader != null) {
31 | try{
32 | bufferedReader.close();
33 | } catch (Exception e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | }
38 | return -1;
39 | }
40 |
41 | public static String getPrintSize(long size) {
42 | if (size < 1024) {
43 | return String.valueOf(size) + "B";
44 | } else {
45 | size = size / 1024;
46 | }
47 | if (size < 1024) {
48 | return String.valueOf(size) + "KB";
49 | } else {
50 | size = size / 1024;
51 | }
52 | if (size < 1024) {
53 | size = size * 100;
54 | return String.valueOf((size / 100)) + "."
55 | + String.valueOf((size % 100)) + "MB";
56 | } else {
57 | size = size * 100 / 1024;
58 | return String.valueOf((size / 100)) + "."
59 | + String.valueOf((size % 100)) + "GB";
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/video/VideoTestActivity.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.video;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 |
7 | import androidx.annotation.Nullable;
8 | import androidx.appcompat.app.AppCompatActivity;
9 | import androidx.fragment.app.FragmentManager;
10 | import androidx.fragment.app.FragmentTransaction;
11 |
12 | import com.mikel.projectdemo.R;
13 | import com.mikel.projectdemo.uiframework.VideoTestFragment;
14 |
15 | public class VideoTestActivity extends AppCompatActivity {
16 |
17 | public static void startActivity(Context context) {
18 | Intent intent = new Intent(context, VideoTestActivity.class);
19 | context.startActivity(intent);
20 | }
21 |
22 | @Override
23 | protected void onCreate(@Nullable Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_video_test);
26 | FragmentManager fragmentManager = getSupportFragmentManager();
27 | VideoTestFragment videoTestFragment = VideoTestFragment.build();
28 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
29 | fragmentTransaction.add(R.id.fragment_container, videoTestFragment);
30 | fragmentTransaction.commit();
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mikel/projectdemo/web/WebViewTestActivity.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo.web;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | public class WebViewTestActivity extends Activity {
8 |
9 | public static void startActivity(Context context) {
10 | Intent intent = new Intent(context, WebViewTestActivity.class);
11 | context.startActivity(intent);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/drawable/image.jpg
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_apm.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
15 |
16 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
48 |
49 |
50 |
51 |
52 |
58 |
59 |
60 |
61 |
69 |
70 |
78 |
79 |
87 |
88 |
96 |
97 |
105 |
106 |
114 |
115 |
123 |
124 |
132 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_detail_poetry.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_paging2_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
12 |
22 |
23 |
33 |
34 |
41 |
42 |
48 |
49 |
53 |
54 |
55 |
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_paging3_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_touch_event_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_video_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_jetpack_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
15 |
16 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_media.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_poetry_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
19 |
20 |
28 |
29 |
39 |
40 |
45 |
46 |
56 |
57 |
63 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_poetry_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
24 |
25 |
31 |
32 |
42 |
43 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sub_tab_content1.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
15 |
19 |
20 |
28 |
29 |
37 |
38 |
46 |
47 |
55 |
56 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sub_tab_content2.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
15 |
19 |
26 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sub_tab_content3.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sub_tab_title1.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sub_tab_title2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_sub_tab_title3.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_tab_jetpack.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_tab_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_tab_media.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_video_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_bottom_sheet_image_video.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
14 |
18 |
26 |
30 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/poetry_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
29 |
30 |
37 |
38 |
44 |
45 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
11 | #00000000
12 | #fcc9c5
13 | #FFFF1826
14 | #f7614d
15 |
16 |
17 |
18 | #008000
19 | #33CC33
20 | #90EE90
21 |
22 | #FF6600
23 | #FF9900
24 | #FFCC66
25 |
26 |
27 | #FFFF00
28 | #FFFF99
29 | #FFFFCC
30 |
31 | #666666
32 | #999999
33 | #CCCCCC
34 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MikelProjectDemo
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/test/java/com/mikel/projectdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.mikel.projectdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/baselib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/baselib/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 |
5 | android {
6 | compileSdkVersion 34
7 | buildToolsVersion "30.0.3"
8 |
9 | defaultConfig {
10 | minSdkVersion 21
11 | targetSdkVersion 34
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | consumerProguardFiles "consumer-rules.pro"
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | compileOptions {
26 | sourceCompatibility JavaVersion.VERSION_1_8
27 | targetCompatibility JavaVersion.VERSION_1_8
28 | }
29 | }
30 |
31 | dependencies {
32 |
33 | implementation 'androidx.appcompat:appcompat:1.2.0'
34 | implementation 'com.google.android.material:material:1.2.1'
35 | testImplementation 'junit:junit:4.+'
36 | androidTestImplementation 'androidx.test.ext:junit:1.1.2'
37 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
38 |
39 | //添加okhttp依赖
40 | api 'com.squareup.okhttp3:okhttp:4.4.0'
41 |
42 | //添加retrofit依赖
43 | api 'com.squareup.retrofit2:retrofit:2.5.0'
44 | api 'com.squareup.retrofit2:converter-gson:2.5.0'
45 | api 'com.squareup.retrofit2:converter-scalars:2.5.0'
46 | api 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'//支持RxJavaCallAdapterFactory
47 |
48 | //添加rxjava2依赖
49 | api 'io.reactivex.rxjava2:rxjava:2.2.9'
50 | api 'io.reactivex.rxjava2:rxandroid:2.1.1'
51 |
52 | //paging2
53 | // implementation "androidx.paging:paging-runtime:2.1.0"
54 |
55 | //paging3
56 | api "androidx.paging:paging-runtime:3.0.1"
57 | api "androidx.paging:paging-rxjava2:3.0.1"
58 |
59 | //添加room依赖
60 | // add for room
61 | api "android.arch.persistence.room:runtime:1.1.1"
62 | // room 配合 RxJava
63 | api "android.arch.persistence.room:rxjava2:1.1.1"
64 | annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
65 |
66 | //ui recyclerView依赖添加
67 | api 'androidx.recyclerview:recyclerview:1.2.0'
68 |
69 | //exoplayer
70 | // api 'com.google.android.exoplayer:exoplayer:2.19.1'
71 | api("androidx.media3:media3-exoplayer:1.2.0")
72 | api("androidx.media3:media3-session:1.2.0")
73 | api("androidx.media3:media3-ui:1.2.0")
74 |
75 | //video cache
76 | api 'com.danikula:videocache:2.7.1'
77 | //glide
78 | api 'com.github.bumptech.glide:glide:4.11.0'
79 |
80 | api project((':nativelib'))
81 | }
--------------------------------------------------------------------------------
/baselib/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/baselib/consumer-rules.pro
--------------------------------------------------------------------------------
/baselib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/baselib/src/androidTest/java/com/mikel/baselib/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.mikel.baselib;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.mikel.baselib.test", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/baselib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/baselib/src/main/java/com/mikel/baselib/manager/ThreadManager.java:
--------------------------------------------------------------------------------
1 | package com.mikel.baselib.manager;
2 |
3 | import android.util.Log;
4 |
5 | import java.util.concurrent.ArrayBlockingQueue;
6 | import java.util.concurrent.LinkedBlockingQueue;
7 | import java.util.concurrent.RejectedExecutionHandler;
8 | import java.util.concurrent.ThreadPoolExecutor;
9 | import java.util.concurrent.TimeUnit;
10 |
11 | public class ThreadManager {
12 | private static final String TAG = "ThreadManager";
13 | private static ThreadManager instence = null;
14 | private ThreadPoolExecutor mThreadPoolExecutor;
15 | //核心线程数
16 | private int corePoolSize = 5;
17 | //最大线程数
18 | private int maximumPoolSize = 10;
19 | //空闲线程的空闲时间
20 | private long keepAliveTime = 10;
21 | //等待执行的容器容量大小
22 | private int capacity = 10;
23 | //任务等待队列
24 | private LinkedBlockingQueue waitingTasksQueue =new LinkedBlockingQueue();
25 |
26 | public synchronized static ThreadManager getInstence() {
27 | if (instence == null) {
28 | synchronized (ThreadManager.class) {
29 | if (instence == instence) {
30 | instence = new ThreadManager();
31 | }
32 | }
33 | }
34 | return instence;
35 | }
36 |
37 | /**
38 | * 构造方法里面就初始化线程池
39 | * ArrayBlockingQueue是一个执行任务的容量,当调用mThreadPoolExecutor的execute,容量加1,执行run完后,容量减1
40 | * ArrayBlockingQueue后面传入true就是以FIFO规则存储:先进先出
41 | */
42 | public ThreadManager() {
43 | if(mThreadPoolExecutor==null) {
44 | mThreadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS,
45 | new ArrayBlockingQueue(capacity,true), handler);
46 | }
47 | mThreadPoolExecutor.execute(runnable);
48 | }
49 |
50 |
51 | /**
52 | * 往队列里面存入可执行任务
53 | * @param runnable
54 | */
55 | public void postTask(Runnable runnable){
56 | try {
57 | waitingTasksQueue.put(runnable);
58 | } catch (InterruptedException e) {
59 | e.printStackTrace();
60 | }
61 | }
62 |
63 | private Runnable runnable=new Runnable() {
64 |
65 | @Override
66 | public void run() {
67 | //开启循环
68 | while(true){
69 | //取出等待的执行任务
70 | Runnable taskQueueRunnable = null;
71 | try {
72 | Log.d(TAG,"等待队列Size:" + waitingTasksQueue.size());
73 | taskQueueRunnable = (Runnable) waitingTasksQueue.take();
74 | } catch (InterruptedException e) {
75 | e.printStackTrace();
76 | }
77 | if(runnable != null){
78 | mThreadPoolExecutor.execute(taskQueueRunnable);
79 | }
80 | Log.d(TAG,"线程池大小" + mThreadPoolExecutor.getPoolSize());
81 | }
82 | }
83 | };
84 |
85 | /**
86 | * 拒绝策略
87 | * 当ArrayBlockingQueue容量过大,就要执行拒绝策略
88 | *
89 | */
90 | private RejectedExecutionHandler handler = new RejectedExecutionHandler(){
91 |
92 | @Override
93 | public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
94 | try {
95 | waitingTasksQueue.put(r);
96 | } catch (InterruptedException e) {
97 | e.printStackTrace();
98 | }
99 | }
100 | };
101 | }
102 |
103 |
--------------------------------------------------------------------------------
/baselib/src/main/java/com/mikel/baselib/utils/AppUtil.java:
--------------------------------------------------------------------------------
1 | package com.mikel.baselib.utils;
2 |
3 | import android.content.Context;
4 |
5 | public class AppUtil {
6 | private static Context mApplicationContext;
7 | public static void setApplicationContext(Context applicationContext) {
8 | mApplicationContext = applicationContext;
9 | }
10 |
11 | public static Context getApplicationContext() {
12 | return mApplicationContext;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/baselib/src/main/java/com/mikel/baselib/utils/DisplayUtil.java:
--------------------------------------------------------------------------------
1 | package com.mikel.baselib.utils;
2 |
3 | import android.content.Context;
4 |
5 | public class DisplayUtil {
6 | public static int dp2px(Context context, int dp) {
7 | float density = context.getResources().getDisplayMetrics().density;
8 | return (int) (dp * density + 0.5f);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/baselib/src/test/java/com/mikel/baselib/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.mikel.baselib;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 | dependencies {
8 | classpath "com.android.tools.build:gradle:7.1.2"
9 | //todo matrix
10 | classpath ("com.tencent.matrix:matrix-gradle-plugin:${lib_thirds_matrix_version}") { changing = true }
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | google()
19 | mavenCentral()
20 | jcenter() // Warning: this repository is going to shut down soon
21 | }
22 | }
23 |
24 | task clean(type: Delete) {
25 | delete rootProject.buildDir
26 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 |
18 | android.useAndroidX=true
19 | android.enableJetifier=true
20 |
21 | #todo matrix
22 | lib_thirds_matrix_version=2.1.0
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Feb 27 11:47:09 CST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file must *NOT* be checked into Version Control Systems,
2 | # as it contains information specific to your local configuration.
3 | #
4 | # Location of the SDK. This is only used by Gradle.
5 | # For customization when using a Version Control System, please read the
6 | # header note.
7 | #Fri Jul 08 10:31:57 CST 2022
8 | sdk.dir=/Users/luohaiming/Library/Android/sdk
9 |
--------------------------------------------------------------------------------
/mmkv/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/mmkv/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 |
5 | android {
6 | namespace 'com.mikel.mmkv'
7 | compileSdkVersion 34
8 |
9 | defaultConfig {
10 | minSdkVersion 24
11 |
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | consumerProguardFiles "consumer-rules.pro"
14 | }
15 |
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 | compileOptions {
23 | sourceCompatibility JavaVersion.VERSION_1_8
24 | targetCompatibility JavaVersion.VERSION_1_8
25 | }
26 | }
27 |
28 | dependencies {
29 | implementation 'androidx.appcompat:appcompat:1.2.0'
30 | implementation 'com.google.android.material:material:1.2.1'
31 | implementation 'com.tencent:mmkv:1.2.14'
32 | }
--------------------------------------------------------------------------------
/mmkv/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/mmkv/consumer-rules.pro
--------------------------------------------------------------------------------
/mmkv/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/mmkv/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/mmkv/src/main/java/com/mikel/mmkv/IMMKVProvider.java:
--------------------------------------------------------------------------------
1 | package com.mikel.mmkv;
2 |
3 | import android.content.SharedPreferences;
4 |
5 | public interface IMMKVProvider {
6 | SharedPreferences getSuperSharedPreferences(String fileName, int i);
7 | }
8 |
--------------------------------------------------------------------------------
/mmkv/src/main/java/com/mikel/mmkv/MMKVProvider.java:
--------------------------------------------------------------------------------
1 | package com.mikel.mmkv;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | import java.util.concurrent.ConcurrentHashMap;
7 |
8 | public class MMKVProvider {
9 | private static volatile MMKVProvider INSTANCE;
10 | public static MMKVProvider getInstance() {
11 | if (INSTANCE == null) {
12 | synchronized (MMKVProvider.class) {
13 | if (INSTANCE == null) {
14 | INSTANCE = new MMKVProvider();
15 | }
16 | }
17 | }
18 | return INSTANCE;
19 | }
20 |
21 | private ConcurrentHashMap instanceMap = new ConcurrentHashMap<>();
22 |
23 | public SharedPreferences getSharedPreferences(Context context, String name, int mode) {
24 | return getMMKVPreferences(context, name, mode);
25 | }
26 |
27 |
28 | private MMKVSP getMMKVPreferences(Context context, String name, int mode) {
29 | MMKVSP mmkvPreferences = instanceMap.get(name);
30 | if (mmkvPreferences != null) {
31 | return mmkvPreferences;
32 | }
33 |
34 | mmkvPreferences = new MMKVSP(context, name, mode == Context.MODE_MULTI_PROCESS);
35 | instanceMap.put(name, mmkvPreferences);
36 | return mmkvPreferences;
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/mmkv/src/main/java/com/mikel/mmkv/MMKVUtils.java:
--------------------------------------------------------------------------------
1 | package com.mikel.mmkv;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | public class MMKVUtils {
7 | public static SharedPreferences getDefaultSharedPreferences(Context context, int mode) {
8 | return MMKVProvider.getInstance().getSharedPreferences(context,
9 | getDefaultSharedPreferencesName(context), mode);
10 | }
11 |
12 | public static String getDefaultSharedPreferencesName(Context context) {
13 | return context.getPackageName() + "_preferences";
14 | }
15 |
16 | public static SharedPreferences getSharedPreferences(Context context, String name, int mode) {
17 | return MMKVProvider.getInstance().getSharedPreferences(context, name, mode);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/nativelib/.cxx/abi_configuration_5g453p2q.json:
--------------------------------------------------------------------------------
1 | {
2 | "allAbis": [
3 | "armeabi-v7a",
4 | "arm64-v8a"
5 | ],
6 | "validAbis": [
7 | "ARMEABI_V7A",
8 | "ARM64_V8A"
9 | ]
10 | }
--------------------------------------------------------------------------------
/nativelib/.cxx/abi_configuration_5g453p2q.log:
--------------------------------------------------------------------------------
1 | []
--------------------------------------------------------------------------------
/nativelib/.cxx/abi_configuration_5g453p2q_key.json:
--------------------------------------------------------------------------------
1 | {
2 | "ndkHandlerSupportedAbis": [
3 | "ARMEABI_V7A",
4 | "ARM64_V8A",
5 | "X86",
6 | "X86_64"
7 | ],
8 | "ndkHandlerDefaultAbis": [
9 | "ARMEABI_V7A",
10 | "ARM64_V8A",
11 | "X86",
12 | "X86_64"
13 | ],
14 | "externalNativeBuildAbiFilters": [],
15 | "ndkConfigAbiFilters": [
16 | "armeabi-v7a",
17 | "arm64-v8a"
18 | ],
19 | "splitsFilterAbis": [],
20 | "ideBuildOnlyTargetAbi": true
21 | }
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/3.10.2/CMakeCCompiler.cmake:
--------------------------------------------------------------------------------
1 | set(CMAKE_C_COMPILER "/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang")
2 | set(CMAKE_C_COMPILER_ARG1 "")
3 | set(CMAKE_C_COMPILER_ID "Clang")
4 | set(CMAKE_C_COMPILER_VERSION "9.0")
5 | set(CMAKE_C_COMPILER_VERSION_INTERNAL "")
6 | set(CMAKE_C_COMPILER_WRAPPER "")
7 | set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "11")
8 | set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert")
9 | set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes")
10 | set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros")
11 | set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert")
12 |
13 | set(CMAKE_C_PLATFORM_ID "")
14 | set(CMAKE_C_SIMULATE_ID "")
15 | set(CMAKE_C_SIMULATE_VERSION "")
16 |
17 |
18 |
19 | set(CMAKE_AR "/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-ar")
20 | set(CMAKE_C_COMPILER_AR "CMAKE_C_COMPILER_AR-NOTFOUND")
21 | set(CMAKE_RANLIB "/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-ranlib")
22 | set(CMAKE_C_COMPILER_RANLIB "CMAKE_C_COMPILER_RANLIB-NOTFOUND")
23 | set(CMAKE_LINKER "/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-ld")
24 | set(CMAKE_COMPILER_IS_GNUCC )
25 | set(CMAKE_C_COMPILER_LOADED 1)
26 | set(CMAKE_C_COMPILER_WORKS TRUE)
27 | set(CMAKE_C_ABI_COMPILED TRUE)
28 | set(CMAKE_COMPILER_IS_MINGW )
29 | set(CMAKE_COMPILER_IS_CYGWIN )
30 | if(CMAKE_COMPILER_IS_CYGWIN)
31 | set(CYGWIN 1)
32 | set(UNIX 1)
33 | endif()
34 |
35 | set(CMAKE_C_COMPILER_ENV_VAR "CC")
36 |
37 | if(CMAKE_COMPILER_IS_MINGW)
38 | set(MINGW 1)
39 | endif()
40 | set(CMAKE_C_COMPILER_ID_RUN 1)
41 | set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
42 | set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
43 | set(CMAKE_C_LINKER_PREFERENCE 10)
44 |
45 | # Save compiler ABI information.
46 | set(CMAKE_C_SIZEOF_DATA_PTR "8")
47 | set(CMAKE_C_COMPILER_ABI "ELF")
48 | set(CMAKE_C_LIBRARY_ARCHITECTURE "")
49 |
50 | if(CMAKE_C_SIZEOF_DATA_PTR)
51 | set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
52 | endif()
53 |
54 | if(CMAKE_C_COMPILER_ABI)
55 | set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
56 | endif()
57 |
58 | if(CMAKE_C_LIBRARY_ARCHITECTURE)
59 | set(CMAKE_LIBRARY_ARCHITECTURE "")
60 | endif()
61 |
62 | set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "")
63 | if(CMAKE_C_CL_SHOWINCLUDES_PREFIX)
64 | set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}")
65 | endif()
66 |
67 |
68 |
69 |
70 |
71 | set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "gcc;dl;c;gcc;dl")
72 | set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/9.0.9/lib/linux/aarch64;/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/lib/gcc/aarch64-linux-android/4.9.x;/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/aarch64-linux-android/lib64;/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/21;/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android;/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/aarch64-linux-android/lib;/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib")
73 | set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
74 |
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/3.10.2/CMakeDetermineCompilerABI_C.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/3.10.2/CMakeDetermineCompilerABI_C.bin
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/3.10.2/CMakeDetermineCompilerABI_CXX.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/3.10.2/CMakeDetermineCompilerABI_CXX.bin
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/3.10.2/CMakeSystem.cmake:
--------------------------------------------------------------------------------
1 | set(CMAKE_HOST_SYSTEM "Darwin-21.3.0")
2 | set(CMAKE_HOST_SYSTEM_NAME "Darwin")
3 | set(CMAKE_HOST_SYSTEM_VERSION "21.3.0")
4 | set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
5 |
6 | include("/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/build/cmake/android.toolchain.cmake")
7 |
8 | set(CMAKE_SYSTEM "Android-1")
9 | set(CMAKE_SYSTEM_NAME "Android")
10 | set(CMAKE_SYSTEM_VERSION "1")
11 | set(CMAKE_SYSTEM_PROCESSOR "aarch64")
12 |
13 | set(CMAKE_CROSSCOMPILING "TRUE")
14 |
15 | set(CMAKE_SYSTEM_LOADED 1)
16 |
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/TargetDirectories.txt:
--------------------------------------------------------------------------------
1 | /Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/rebuild_cache.dir
2 | /Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/edit_cache.dir
3 | /Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/native_test.dir
4 |
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/cmake.check_cache:
--------------------------------------------------------------------------------
1 | # This file is generated by cmake for dependency checking of the CMakeCache.txt file
2 |
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/feature_tests.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/feature_tests.bin
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/CMakeFiles/feature_tests.c:
--------------------------------------------------------------------------------
1 |
2 | const char features[] = {"\n"
3 | "C_FEATURE:"
4 | #if ((__clang_major__ * 100) + __clang_minor__) >= 304
5 | "1"
6 | #else
7 | "0"
8 | #endif
9 | "c_function_prototypes\n"
10 | "C_FEATURE:"
11 | #if ((__clang_major__ * 100) + __clang_minor__) >= 304 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
12 | "1"
13 | #else
14 | "0"
15 | #endif
16 | "c_restrict\n"
17 | "C_FEATURE:"
18 | #if ((__clang_major__ * 100) + __clang_minor__) >= 304 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
19 | "1"
20 | #else
21 | "0"
22 | #endif
23 | "c_static_assert\n"
24 | "C_FEATURE:"
25 | #if ((__clang_major__ * 100) + __clang_minor__) >= 304 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
26 | "1"
27 | #else
28 | "0"
29 | #endif
30 | "c_variadic_macros\n"
31 |
32 | };
33 |
34 | int main(int argc, char** argv) { (void)argv; return features[argc]; }
35 |
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/android_gradle_build.json:
--------------------------------------------------------------------------------
1 | {
2 | "stringTable": {},
3 | "buildFiles": [
4 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/CMakeLists.txt"
5 | ],
6 | "cleanCommandsComponents": [
7 | [
8 | "/Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja",
9 | "-C",
10 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a",
11 | "clean"
12 | ]
13 | ],
14 | "buildTargetsCommandComponents": [
15 | "/Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja",
16 | "-C",
17 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a",
18 | "{LIST_OF_TARGETS_TO_BUILD}"
19 | ],
20 | "libraries": {
21 | "native_test-Debug-arm64-v8a": {
22 | "buildCommandComponents": [
23 | "/Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja",
24 | "-C",
25 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a",
26 | "native_test"
27 | ],
28 | "buildType": "debug",
29 | "abi": "arm64-v8a",
30 | "artifactName": "native_test",
31 | "output": "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/jniLibs/arm64-v8a/libnative_test.so",
32 | "runtimeFiles": [
33 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/src/main/jniLibs/arm64-v8a/libaesutil.so"
34 | ]
35 | }
36 | },
37 | "toolchains": {},
38 | "cFileExtensions": [],
39 | "cppFileExtensions": [
40 | "cpp"
41 | ]
42 | }
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/android_gradle_build_mini.json:
--------------------------------------------------------------------------------
1 | {
2 | "buildFiles": [
3 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/CMakeLists.txt"
4 | ],
5 | "cleanCommandsComponents": [
6 | [
7 | "/Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja",
8 | "-C",
9 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a",
10 | "clean"
11 | ]
12 | ],
13 | "buildTargetsCommandComponents": [
14 | "/Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja",
15 | "-C",
16 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a",
17 | "{LIST_OF_TARGETS_TO_BUILD}"
18 | ],
19 | "libraries": {
20 | "native_test-Debug-arm64-v8a": {
21 | "artifactName": "native_test",
22 | "buildCommandComponents": [
23 | "/Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja",
24 | "-C",
25 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a",
26 | "native_test"
27 | ],
28 | "abi": "arm64-v8a",
29 | "output": "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/jniLibs/arm64-v8a/libnative_test.so",
30 | "runtimeFiles": [
31 | "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/src/main/jniLibs/arm64-v8a/libaesutil.so"
32 | ]
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/build_command.txt:
--------------------------------------------------------------------------------
1 | Executable : /Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/cmake
2 | arguments :
3 | -H/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib
4 | -DCMAKE_FIND_ROOT_PATH=/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/prefab/arm64-v8a/prefab
5 | -DCMAKE_BUILD_TYPE=Debug
6 | -DCMAKE_TOOLCHAIN_FILE=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/build/cmake/android.toolchain.cmake
7 | -DANDROID_ABI=arm64-v8a
8 | -DANDROID_NDK=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529
9 | -DANDROID_PLATFORM=android-21
10 | -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a
11 | -DCMAKE_ANDROID_NDK=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529
12 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
13 | -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/build/intermediates/cmake/debug/obj/arm64-v8a
14 | -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/build/intermediates/cmake/debug/obj/arm64-v8a
15 | -DCMAKE_MAKE_PROGRAM=/Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja
16 | -DCMAKE_SYSTEM_NAME=Android
17 | -DCMAKE_SYSTEM_VERSION=21
18 | -DANDROID_STL=c++_shared
19 | -B/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a
20 | -GNinja
21 | jvmArgs :
22 |
23 |
24 | Build command args: []
25 | Version: 1
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/build_file_index.txt:
--------------------------------------------------------------------------------
1 | /Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/CMakeLists.txt
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/cmake_install.cmake:
--------------------------------------------------------------------------------
1 | # Install script for directory: /Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib
2 |
3 | # Set the install prefix
4 | if(NOT DEFINED CMAKE_INSTALL_PREFIX)
5 | set(CMAKE_INSTALL_PREFIX "/usr/local")
6 | endif()
7 | string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
8 |
9 | # Set the install configuration name.
10 | if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
11 | if(BUILD_TYPE)
12 | string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
13 | CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
14 | else()
15 | set(CMAKE_INSTALL_CONFIG_NAME "Debug")
16 | endif()
17 | message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
18 | endif()
19 |
20 | # Set the component getting installed.
21 | if(NOT CMAKE_INSTALL_COMPONENT)
22 | if(COMPONENT)
23 | message(STATUS "Install component: \"${COMPONENT}\"")
24 | set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
25 | else()
26 | set(CMAKE_INSTALL_COMPONENT)
27 | endif()
28 | endif()
29 |
30 | # Install shared libraries without execute permission?
31 | if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
32 | set(CMAKE_INSTALL_SO_NO_EXE "0")
33 | endif()
34 |
35 | # Is this installation the result of a crosscompile?
36 | if(NOT DEFINED CMAKE_CROSSCOMPILING)
37 | set(CMAKE_CROSSCOMPILING "TRUE")
38 | endif()
39 |
40 | if(CMAKE_INSTALL_COMPONENT)
41 | set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
42 | else()
43 | set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
44 | endif()
45 |
46 | string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
47 | "${CMAKE_INSTALL_MANIFEST_FILES}")
48 | file(WRITE "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a/${CMAKE_INSTALL_MANIFEST}"
49 | "${CMAKE_INSTALL_MANIFEST_CONTENT}")
50 |
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/compile_commands.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "directory": "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a",
4 | "command": "/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=aarch64-none-linux-android21 --gcc-toolchain=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64 --sysroot=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -Dnative_test_EXPORTS -I../../../../src/main/cpp/include -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -O0 -fno-limit-debug-info -fPIC -o CMakeFiles/native_test.dir/src/main/cpp/native_test.cpp.o -c /Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/src/main/cpp/native_test.cpp",
5 | "file": "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/src/main/cpp/native_test.cpp"
6 | }
7 | ]
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/compile_commands.json.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/nativelib/.cxx/cmake/debug/arm64-v8a/compile_commands.json.bin
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/json_generation_record.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "level": "INFO",
4 | "message": "Start JSON generation. Platform version: 21 min SDK version: arm64-v8a",
5 | "file": "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/CMakeLists.txt",
6 | "tag": "debug|arm64-v8a",
7 | "diagnosticCode": "UNKNOWN"
8 | },
9 | {
10 | "level": "INFO",
11 | "message": "JSON \u0027/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a/android_gradle_build.json\u0027 was up-to-date",
12 | "file": "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/CMakeLists.txt",
13 | "tag": "debug|arm64-v8a",
14 | "diagnosticCode": "UNKNOWN"
15 | },
16 | {
17 | "level": "INFO",
18 | "message": "JSON generation completed without problems",
19 | "file": "/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/CMakeLists.txt",
20 | "tag": "debug|arm64-v8a",
21 | "diagnosticCode": "UNKNOWN"
22 | }
23 | ]
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/prefab_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": false,
3 | "packages": []
4 | }
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/rules.ninja:
--------------------------------------------------------------------------------
1 | # CMAKE generated file: DO NOT EDIT!
2 | # Generated by "Ninja" Generator, CMake Version 3.10
3 |
4 | # This file contains all the rules used to get the outputs files
5 | # built from the input files.
6 | # It is included in the main 'build.ninja'.
7 |
8 | # =============================================================================
9 | # Project: Project
10 | # Configuration: Debug
11 | # =============================================================================
12 | # =============================================================================
13 |
14 | #############################################
15 | # Rule for running custom commands.
16 |
17 | rule CUSTOM_COMMAND
18 | command = $COMMAND
19 | description = $DESC
20 |
21 |
22 | #############################################
23 | # Rule for compiling CXX files.
24 |
25 | rule CXX_COMPILER__native_test
26 | depfile = $DEP_FILE
27 | deps = gcc
28 | command = /Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=aarch64-none-linux-android21 --gcc-toolchain=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64 --sysroot=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
29 | description = Building CXX object $out
30 |
31 |
32 | #############################################
33 | # Rule for linking CXX shared library.
34 |
35 | rule CXX_SHARED_LIBRARY_LINKER__native_test
36 | command = $PRE_LINK && /Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=aarch64-none-linux-android21 --gcc-toolchain=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64 --sysroot=/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -fPIC $LANGUAGE_COMPILE_FLAGS $ARCH_FLAGS $LINK_FLAGS -shared $SONAME_FLAG$SONAME -o $TARGET_FILE $in $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
37 | description = Linking CXX shared library $TARGET_FILE
38 | restat = $RESTAT
39 |
40 |
41 | #############################################
42 | # Rule for re-running cmake.
43 |
44 | rule RERUN_CMAKE
45 | command = /Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/cmake -H/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib -B/Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/.cxx/cmake/debug/arm64-v8a
46 | description = Re-running CMake...
47 | generator = 1
48 |
49 |
50 | #############################################
51 | # Rule for cleaning all built files.
52 |
53 | rule CLEAN
54 | command = /Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja -t clean
55 | description = Cleaning all built files...
56 |
57 |
58 | #############################################
59 | # Rule for printing all primary targets available.
60 |
61 | rule HELP
62 | command = /Users/luohaiming/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja -t targets
63 | description = All primary targets available:
64 |
65 |
--------------------------------------------------------------------------------
/nativelib/.cxx/cmake/debug/arm64-v8a/symbol_folder_index.txt:
--------------------------------------------------------------------------------
1 | /Users/PokeStudio/AndroidProjects/MikelProjectDemo-github/nativelib/build/intermediates/cmake/debug/obj/arm64-v8a
--------------------------------------------------------------------------------
/nativelib/.cxx/ndk_locator_record_17146en5.json:
--------------------------------------------------------------------------------
1 | {
2 | "ndk": "/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529",
3 | "revision": {
4 | "mMajor": 21,
5 | "mMinor": 4,
6 | "mMicro": 7075529,
7 | "mPreview": 0,
8 | "mPrecision": "MICRO",
9 | "mPreviewSeparator": " "
10 | }
11 | }
--------------------------------------------------------------------------------
/nativelib/.cxx/ndk_locator_record_17146en5.log:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "level": "INFO",
4 | "message": "android.ndkVersion from module build.gradle is [not set]",
5 | "diagnosticCode": "UNKNOWN"
6 | },
7 | {
8 | "level": "INFO",
9 | "message": "android.ndkPath from module build.gradle is not set",
10 | "diagnosticCode": "UNKNOWN"
11 | },
12 | {
13 | "level": "INFO",
14 | "message": "ndk.dir in local.properties is not set",
15 | "diagnosticCode": "UNKNOWN"
16 | },
17 | {
18 | "level": "INFO",
19 | "message": "Not considering ANDROID_NDK_HOME because support was removed after deprecation period.",
20 | "diagnosticCode": "UNKNOWN"
21 | },
22 | {
23 | "level": "INFO",
24 | "message": "sdkFolder is /Users/luohaiming/Library/Android/sdk",
25 | "diagnosticCode": "UNKNOWN"
26 | },
27 | {
28 | "level": "INFO",
29 | "message": "Because no explicit NDK was requested, the default version [21.4.7075529] for this Android Gradle Plugin will be used",
30 | "diagnosticCode": "UNKNOWN"
31 | }
32 | ]
--------------------------------------------------------------------------------
/nativelib/.cxx/ndk_locator_record_17146en5_key.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdkFolder": "/Users/luohaiming/Library/Android/sdk",
3 | "sideBySideNdkFolderNames": [
4 | "24.0.8215888",
5 | "21.4.7075529",
6 | "21.3.6528147",
7 | "21.1.6352462"
8 | ]
9 | }
--------------------------------------------------------------------------------
/nativelib/.cxx/ndk_locator_record_1l5e415f.json:
--------------------------------------------------------------------------------
1 | {
2 | "ndk": "/Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529",
3 | "revision": {
4 | "mMajor": 21,
5 | "mMinor": 4,
6 | "mMicro": 7075529,
7 | "mPreview": 0,
8 | "mPrecision": "MICRO",
9 | "mPreviewSeparator": " "
10 | }
11 | }
--------------------------------------------------------------------------------
/nativelib/.cxx/ndk_locator_record_1l5e415f.log:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "level": "INFO",
4 | "message": "android.ndkVersion from module build.gradle is [not set]",
5 | "diagnosticCode": "UNKNOWN"
6 | },
7 | {
8 | "level": "INFO",
9 | "message": "android.ndkPath from module build.gradle is not set",
10 | "diagnosticCode": "UNKNOWN"
11 | },
12 | {
13 | "level": "INFO",
14 | "message": "ndk.dir in local.properties is not set",
15 | "diagnosticCode": "UNKNOWN"
16 | },
17 | {
18 | "level": "INFO",
19 | "message": "Not considering ANDROID_NDK_HOME because support was removed after deprecation period.",
20 | "diagnosticCode": "UNKNOWN"
21 | },
22 | {
23 | "level": "INFO",
24 | "message": "sdkFolder is /Users/luohaiming/Library/Android/sdk",
25 | "diagnosticCode": "UNKNOWN"
26 | },
27 | {
28 | "level": "INFO",
29 | "message": "Because no explicit NDK was requested, the default version [21.4.7075529] for this Android Gradle Plugin will be used",
30 | "diagnosticCode": "UNKNOWN"
31 | },
32 | {
33 | "level": "INFO",
34 | "message": "Folder /Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529 does not exist. Ignoring.",
35 | "diagnosticCode": "UNKNOWN"
36 | },
37 | {
38 | "level": "INFO",
39 | "message": "Folder /Users/luohaiming/Library/Android/sdk/ndk-bundle does not exist. Ignoring.",
40 | "diagnosticCode": "UNKNOWN"
41 | },
42 | {
43 | "level": "INFO",
44 | "message": "No NDK was found. Trying to download it now.",
45 | "diagnosticCode": "UNKNOWN"
46 | },
47 | {
48 | "level": "INFO",
49 | "message": "NDK 21.4.7075529 was downloaded to /Users/luohaiming/Library/Android/sdk/ndk/21.4.7075529. Using that.",
50 | "diagnosticCode": "UNKNOWN"
51 | }
52 | ]
--------------------------------------------------------------------------------
/nativelib/.cxx/ndk_locator_record_1l5e415f_key.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdkFolder": "/Users/luohaiming/Library/Android/sdk",
3 | "sideBySideNdkFolderNames": [
4 | "24.0.8215888",
5 | "21.3.6528147",
6 | "21.1.6352462"
7 | ]
8 | }
--------------------------------------------------------------------------------
/nativelib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/nativelib/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #构建库文件所需要CMake最小版本
2 | cmake_minimum_required(VERSION 3.4.1)
3 | # 设置生成的so动态库输出的路径
4 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/jniLibs/${ANDROID_ABI})
5 | #添加自己的C/C++源文件
6 | add_library( # Sets the name of the library.
7 | native_test
8 | # Sets the library as a shared library.
9 | SHARED
10 | # Provides a relative path to your source file(s).
11 | src/main/cpp/native_test.cpp)
12 | #添加依赖的NDK 库
13 | find_library( # Sets the name of the path variable.
14 | log-lib
15 | # Specifies the name of the NDK library that
16 | # you want CMake to locate.
17 | log )
18 |
19 | #添加外部依赖的so
20 | add_library(
21 | aesutil
22 | SHARED
23 | IMPORTED)
24 | set_target_properties(
25 | aesutil
26 | PROPERTIES IMPORTED_LOCATION
27 | ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libaesutil.so
28 | )
29 | include_directories(src/main/cpp/include)
30 |
31 | #将目标库与NDK 中的库链接
32 | target_link_libraries( # Specifies the target library.
33 | native_test
34 | # Links the target library to the log library
35 | # included in the NDK.
36 | aesutil
37 | ${log-lib} )
--------------------------------------------------------------------------------
/nativelib/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 |
5 | android {
6 | compileSdkVersion 34
7 | defaultConfig {
8 | minSdkVersion 21
9 | targetSdkVersion 34
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | consumerProguardFiles "consumer-rules.pro"
14 | //1. android-defaultConfig {}下 externalNativeBuild cmake path
15 | externalNativeBuild {
16 | cmake {
17 | cppFlags ""
18 | arguments "-DANDROID_STL=c++_shared"
19 | }
20 | }
21 | //2. android-defaultConfig {}下 选择生成的CPU 架构, android defaultConfig下定义
22 | ndk{
23 | abiFilters "armeabi-v7a", "arm64-v8a"
24 | }
25 | }
26 |
27 | buildTypes {
28 | release {
29 | minifyEnabled false
30 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
31 | }
32 | }
33 | compileOptions {
34 | sourceCompatibility JavaVersion.VERSION_1_8
35 | targetCompatibility JavaVersion.VERSION_1_8
36 | }
37 |
38 | //3. android{}下 externalNativeBuild cmake path
39 | externalNativeBuild {
40 | cmake {
41 | path "CMakeLists.txt"
42 | }
43 | }
44 | sourceSets {
45 | main {
46 | jniLibs.srcDirs = ['libs']
47 | }
48 | }
49 | }
50 |
51 | dependencies {
52 |
53 | implementation 'androidx.appcompat:appcompat:1.2.0'
54 | implementation 'com.google.android.material:material:1.3.0'
55 | testImplementation 'junit:junit:4.+'
56 | androidTestImplementation 'androidx.test.ext:junit:1.1.2'
57 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
58 | }
--------------------------------------------------------------------------------
/nativelib/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/nativelib/consumer-rules.pro
--------------------------------------------------------------------------------
/nativelib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/nativelib/readme.txt:
--------------------------------------------------------------------------------
1 | add2line还原native堆栈:
2 | D:\media\sdk\ndk\21.3.6528147\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin>aarch64-linux-android-addr2line.exe
3 | -f -e
4 | D:\media\gitProjects\MikelProjectDemo\nativelib\build\intermediates\cmake\debug\obj\arm64-v8a\libnative_test.so
5 | 堆栈:
6 | 0000000000000dd0 0000000000000d98
7 |
8 | D:\media\sdk\ndk\21.3.6528147\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin
--------------------------------------------------------------------------------
/nativelib/src/androidTest/java/com/mikel/natvelib/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.mikel.natvelib;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.mikel.natvelib.test", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/nativelib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/nativelib/src/main/cpp/include/aes.h:
--------------------------------------------------------------------------------
1 | #ifndef AES_H
2 | #define AES_H
3 |
4 | #include
5 |
6 | class AES
7 | {
8 | public:
9 | AES(unsigned char* key);
10 | virtual ~AES();
11 | unsigned char* Cipher(unsigned char* input);
12 | unsigned char* InvCipher(unsigned char* input);
13 | void* Cipher(void* input, int length=0);
14 | void* InvCipher(void* input, int length);
15 |
16 | void Cipher(char *input, char *output);
17 | void InvCipher(char *inut, char *output);
18 |
19 | private:
20 | unsigned char Sbox[256];
21 | unsigned char InvSbox[256];
22 | unsigned char ww[11][4][4];
23 |
24 | void KeyExpansion(unsigned char* key, unsigned char w[][4][4]);
25 | unsigned char FFmul(unsigned char a, unsigned char b);
26 |
27 | void SubBytes(unsigned char state[][4]);
28 | void ShiftRows(unsigned char state[][4]);
29 | void MixColumns(unsigned char state[][4]);
30 | void AddRoundKey(unsigned char state[][4], unsigned char k[][4]);
31 |
32 | void InvSubBytes(unsigned char state[][4]);
33 | void InvShiftRows(unsigned char state[][4]);
34 | void InvMixColumns(unsigned char state[][4]);
35 |
36 | int strToHex(const char *ch, char *hex);
37 | int hexToStr(const char *hex, char *ch);
38 | int ascillToValue(const char ch);
39 | char valueToHexCh(const int value);
40 | int getUCharLen(const unsigned char *uch);
41 | int strToUChar(const char *ch, unsigned char *uch);
42 | int ucharToStr(const unsigned char *uch, char *ch);
43 | int ucharToHex(const unsigned char *uch, char *hex);
44 | int hexToUChar(const char *hex, unsigned char *uch);
45 | };
46 |
47 | #endif // AES_H
48 |
--------------------------------------------------------------------------------
/nativelib/src/main/java/com/mikel/nativelib/JNIHelper.java:
--------------------------------------------------------------------------------
1 | package com.mikel.nativelib;
2 |
3 | public class JNIHelper {
4 | static {
5 | System.loadLibrary("native_test");
6 | }
7 |
8 | /***
9 | * 静态注册
10 | * @return
11 | */
12 | public static native String testJNI();
13 | public static native String encryptJNI(String originStr);
14 | public static native String decryptJNI(String enCodeStr);
15 |
16 | /**
17 | * 动态注册
18 | */
19 | public static native String dynamicMethodTest(int intValue, float floatValue, double doubleValue, byte bteValue,
20 | String strValue, boolean boolValue,
21 | int[] intArrayValue, float[] floatArrayValue, double[] doubleArrayValue,
22 | byte[] byteArrayValue, boolean[] boolArrayValue);
23 | }
--------------------------------------------------------------------------------
/nativelib/src/main/jniLibs/arm64-v8a/libaesutil.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/nativelib/src/main/jniLibs/arm64-v8a/libaesutil.so
--------------------------------------------------------------------------------
/nativelib/src/main/jniLibs/armeabi-v7a/libaesutil.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikelhm/MikelProjectDemo/ecdacc3137137a621ce0946fc5b4e2b5431aa90c/nativelib/src/main/jniLibs/armeabi-v7a/libaesutil.so
--------------------------------------------------------------------------------
/nativelib/src/test/java/com/mikel/natvelib/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.mikel.natvelib;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = "MikelProjectDemo"
2 | include ':app'
3 | include ':baselib'
4 | include ':nativelib'
5 | include ':apm'
6 | include ':apmlib'
7 | include ':mmkv'
8 |
--------------------------------------------------------------------------------