├── .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 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 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 | --------------------------------------------------------------------------------