diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100755 index 0000000..5b618fb --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index f31ab3f..8249978 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ # 教训:自由的世界也是有规则的 + # 关于本Demo-组件化的工程架构With MVP,Dagger2.android,RXjava2 一直在纠结在何种开发模式之中,重构希望能把关注点集中到代码结构、整体架构、可测试性、可维护性这四个方面 @@ -47,7 +48,7 @@ 如果没有[Dagger.android](https://google.github.io/dagger//android.html) 我是不想使用dagger2的。写下面的类似代码实在太多了 - 我自己翻译的官方的链接:https://www.jianshu.com/p/879e0fe4ef36 + 我自己翻译的关于Dagger Android 的文章:https://www.jianshu.com/p/879e0fe4ef36 。刚开始使用会比较难上手 ``` public class FrombulationActivity extends Activity { @@ -71,20 +72,6 @@ ``` - -# 关于热修复 - 阿里的HotFix&微信的Tinker - android的热修复原理大体上分为两种,其一是通过dex的执行顺序实现Apk热修复的功能(Tinker),但是其需要将App重启才能生 效;其二是通过Native修改函数指针的方式实现热修复(HotFix)。 - - 显然对于修复紧急BUG这个场景,阿里百川HotFix的更为合适,它更加轻量,可以在不重启的情况下生效,且对性能几乎没有影 - 微信Tinker、QQ空间超级补丁技术更多地把场景定位在发布小的新功能上,采用ClassLoader的模式,牺牲较高的性能代价去实现 类、资源新增或替换的功能。 - 阿里百川HotFix对应用本身做到无侵入,无性能损耗。 - - [2017年6月阿里手淘推出了首个非侵入式移动热更新解决方案——Sophix。 - 在Android热修复的三大领域:代码修复、资源修复、SO修复方面,以及方案的安全性和易用性方面,Sophix都做到了业界领先,可是要收费](https://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650823404&idx=1&sn=c56458a97561f54b893b33a80635d399&chksm=80b78e72b7c00764b26972bd21cd3e4fe5bb075a8d80890340b2a7a0a565779add0757b161e8&mpshare=1&scene=1&srcid=0704C7XraNsOGvDsgN9bCNii&pass_ticket=AZhM9mvZM8BzU28oFsdChz0QSuCBcgFEhhet1%2FD2hXnrM%2FSkdWA5TsZ06l%2F%2Fhbwm#rd) - - - # 项目中包含的基本的通用模块 - Dagger.android 大大的优化Dagger 在android 中的使用, - BaseActivity 中Toolbar 的处理 diff --git a/app/src/main/java/com/zenglb/framework/AppComponent.java b/app/src/main/java/com/zenglb/framework/AppComponent.java index 355a14c..e174eb3 100644 --- a/app/src/main/java/com/zenglb/framework/AppComponent.java +++ b/app/src/main/java/com/zenglb/framework/AppComponent.java @@ -46,6 +46,6 @@ */ public interface AppComponent { - void inject(BaseApplication application); + void inject(BaseApplication application); // } diff --git a/baselib/AnyLife_Zlb_Keystore b/baselib/AnyLife_Zlb_Keystore new file mode 100644 index 0000000..2a37802 Binary files /dev/null and b/baselib/AnyLife_Zlb_Keystore differ diff --git a/baselib/build.gradle b/baselib/build.gradle index 0295873..2301962 100644 --- a/baselib/build.gradle +++ b/baselib/build.gradle @@ -64,7 +64,7 @@ dependencies { api "com.android.support:support-annotations:$rootProject.ext.supportLibraryVersion" api "com.android.support:cardview-v7:$rootProject.ext.supportLibraryVersion" -// api 'com.google.android.gms:play-services-ads:17.1.1' +// api 'com.google.android.gms:play-services-ads:17.1.1' // !!! api 'com.google.firebase:firebase-ads:17.1.3' //所有的东西都集中到了FireBase @@ -91,7 +91,7 @@ dependencies { api 'com.github.GrenderG:Toasty:1.2.5' api 'com.google.code.gson:gson:2.8.4' - api 'com.kingja.loadsir:loadsir:1.3.5' + api 'com.kingja.loadsir:loadsir:1.3.6' api 'pub.devrel:easypermissions:2.0.1' //没有其他的原因,其他的目前多少有BUG 啊 @@ -110,7 +110,6 @@ dependencies { //Http Request log debugImplementation 'com.readystatesoftware.chuck:library:1.1.0' - api 'com.github.florent37:singledateandtimepicker:1.2.2' //高仿IOS 时间选择 api 'de.hdodenhof:circleimageview:2.2.0' //CircleImageView api 'com.android.support.constraint:constraint-layout:1.1.3' @@ -124,7 +123,7 @@ dependencies { annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1' api 'com.journeyapps:zxing-android-embedded:3.6.0' //只是为了简单 - api 'org.greenrobot:eventbus:3.1.1' //本来不像引用太多第三方,但是目前的通信实在烦人 + api 'org.greenrobot:eventbus:3.1.1' //本来不像引用太多第三方,但是目前的通信实在烦人 ------ api project(':component-base') @@ -135,5 +134,9 @@ dependencies { api 'anylife.scrolltextview:ScrollTextviewLib:1.4.2' //滚动字幕 +// debugImplementation project(':library') //debug 版本直接引用本地项目 +// releaseImplementation '远程库地址' //release 版本引用远程版本用来最终测试发现问题 + +// implementation fileTree(include: ['*.aar'], dir: 'libs/xxx') //gradle 在编译前就会自动进到 xxx 目录下面,遍历并引用所有 aar 文件 } diff --git a/baselib/src/main/AndroidManifest.xml b/baselib/src/main/AndroidManifest.xml index f6104f7..57bb09d 100644 --- a/baselib/src/main/AndroidManifest.xml +++ b/baselib/src/main/AndroidManifest.xml @@ -4,7 +4,7 @@ - + diff --git a/baselib/src/main/java/com/zlb/Sp/SPDao.java b/baselib/src/main/java/com/zlb/Sp/SPDao.java index 527cc62..caf41a2 100644 --- a/baselib/src/main/java/com/zlb/Sp/SPDao.java +++ b/baselib/src/main/java/com/zlb/Sp/SPDao.java @@ -5,14 +5,11 @@ import android.support.annotation.NonNull; import android.util.Log; - /** * 存储key-value 数据,支持加密 * SharedPreferencesDao 就是操作SP * Created by anylife.zlb@gmail.com on 2016/11/8. */ - -// TODO: 2018/1/12 最好还是和不同的账号分开来,和DAOSession 一样 public class SPDao { private static final String TAG = SPDao.class.getSimpleName(); private static final String SharedPreferencesName = "AAAAAAA-Vanke"; diff --git a/baselib/src/main/java/com/zlb/base/BaseApplication.java b/baselib/src/main/java/com/zlb/base/BaseApplication.java index c0c2a2e..77c5a30 100644 --- a/baselib/src/main/java/com/zlb/base/BaseApplication.java +++ b/baselib/src/main/java/com/zlb/base/BaseApplication.java @@ -69,7 +69,7 @@ public AndroidInjector serviceInjector() { private static Context appContext; @Inject - NtpUtils ntpUtils; + NtpUtils ntpUtils; // @Override public void onCreate() { @@ -159,7 +159,7 @@ private void initARouter() { /** - * 判断App是否是Debug版本 + * 判断App是否是Debug版本. * * @return {@code true}: 是
{@code false}: 否 */ diff --git a/baselib/src/main/java/com/zlb/base/BaseMVPActivity.java b/baselib/src/main/java/com/zlb/base/BaseMVPActivity.java index cccd8b0..4abe7cc 100644 --- a/baselib/src/main/java/com/zlb/base/BaseMVPActivity.java +++ b/baselib/src/main/java/com/zlb/base/BaseMVPActivity.java @@ -25,7 +25,11 @@ public abstract class BaseMVPActivity extends BaseActivity implements HasSupport @Override protected void onCreate(@Nullable Bundle savedInstanceState) { - //一处声明,处处依赖注入,before calling super.onCreate();: + /** + * 一处注入就好了,处处使用。 + * + * + */ AndroidInjection.inject(this); super.onCreate(savedInstanceState); diff --git a/baselib/src/main/java/com/zlb/dagger/component/BaseActivityComponent.java b/baselib/src/main/java/com/zlb/dagger/component/BaseActivityComponent.java index eefd8cf..48cba27 100644 --- a/baselib/src/main/java/com/zlb/dagger/component/BaseActivityComponent.java +++ b/baselib/src/main/java/com/zlb/dagger/component/BaseActivityComponent.java @@ -7,9 +7,13 @@ import dagger.android.AndroidInjector; /** + * * 在 {@link BaseActivityComponent} 等中被使用 * 不要在每个Activity 中建立一个ActivitySubComponent,麻烦而且重复的无聊代码 * + * 每一个继承BaseActivity(BaseMVPActivity)的Activity,都共享同一个SubComponent + * 这样能减少非常多的重复的无聊的代码 + * * Created by anylife.zlb@gmail.com on 2018/1/11. */ @Subcomponent(modules = { @@ -18,7 +22,7 @@ public interface BaseActivityComponent extends AndroidInjector { - //每一个继承BaseActivity的Activity,都共享同一个SubComponent + //每一个继承BaseActivity(BaseMVPActivity)的Activity,都共享同一个SubComponent @Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder { diff --git a/baselib/src/main/java/com/zlb/dagger/module/BaseGlobalModule.java b/baselib/src/main/java/com/zlb/dagger/module/BaseGlobalModule.java index 77591df..5d090db 100644 --- a/baselib/src/main/java/com/zlb/dagger/module/BaseGlobalModule.java +++ b/baselib/src/main/java/com/zlb/dagger/module/BaseGlobalModule.java @@ -58,6 +58,8 @@ public Context provideContext() { @Provides @Singleton //在这加了Singleton 的注解就是单例的了,打出内存地址查看一下 public SPDao provideSPDao() { + + //todo 既然Not third part .why not inject ? return new SPDao(mContext); } diff --git a/baselib/src/main/java/com/zlb/utils/ntp/NtpUtils.java b/baselib/src/main/java/com/zlb/utils/ntp/NtpUtils.java index 0574c18..a4c71ed 100644 --- a/baselib/src/main/java/com/zlb/utils/ntp/NtpUtils.java +++ b/baselib/src/main/java/com/zlb/utils/ntp/NtpUtils.java @@ -18,6 +18,8 @@ /** * 时间校准Utils + * + * */ public class NtpUtils { diff --git a/gradle.properties b/gradle.properties index 7f4013b..1ed6af6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ org.gradle.jvmargs=-Xmx1536m ##是不是组件化开发调试模式 -#isModule=true +isModule=true #是不是组件化开发调试模式 -isModule=false +#isModule=false diff --git a/module_main/src/main/java/com/anylife/module_main/business/login/LoginActivity.java b/module_main/src/main/java/com/anylife/module_main/business/login/LoginActivity.java index 8c08879..850909d 100644 --- a/module_main/src/main/java/com/anylife/module_main/business/login/LoginActivity.java +++ b/module_main/src/main/java/com/anylife/module_main/business/login/LoginActivity.java @@ -99,7 +99,7 @@ protected void initViews() { etPassword = findViewById(R.id.et_password); loginBtn = findViewById(R.id.login_btn); - loginBtn.setOnClickListener(view -> mvpLogin()); + loginBtn.setOnClickListener(view -> goLogin()); cardview = findViewById(R.id.cardview); @@ -123,7 +123,7 @@ protected void initViews() { * 外网暂不支持访问 * */ - public void mvpLogin() { + public void goLogin() { String userName = etUsername.getText().toString().trim(); String password = etPassword.getText().toString().trim(); @@ -151,7 +151,7 @@ public void onSuccess(LoginResult loginResult) { public void onFailure(int code, String message) { super.onFailure(code, message); - //去吧 + //外网暂不支持访问 ,但是里面的新闻接口是没有限制的 Intent i2 = new Intent(LoginActivity.this, MainActivityBottomNavi.class); startActivity(i2); LoginActivity.this.finish(); diff --git a/module_main/src/main/java/com/anylife/module_main/dagger/MainModuleAllActivityModule.java b/module_main/src/main/java/com/anylife/module_main/dagger/MainModuleAllActivityModule.java index b1f23cf..62d2f89 100644 --- a/module_main/src/main/java/com/anylife/module_main/dagger/MainModuleAllActivityModule.java +++ b/module_main/src/main/java/com/anylife/module_main/dagger/MainModuleAllActivityModule.java @@ -19,27 +19,22 @@ * 新建了一个Activity 的并且需要inject 的只需要添加两行代码 *

* 大部分的页面都不需要再额外的提供对象的话只需要DefaultActivityModule 就好了,否则自定义XXActivityModule - *

- *

+ * + * * 对个人而言,这样的好处在于: * 1.每次不再需要额外声明一个SubCompoent,再次减少模板代码 * 2.每个Activity的Module都放在同一个AllActivitysModule中进行统一管理,每次修改只需要修改这一个类即可 * 3.每个Activity所单独需要的依赖,依然由各自的Module进行管理和实例化,依然没有任何耦合 */ @Module(subcomponents = { - BaseActivityComponent.class //1111111111 subcomponent=BaseActivityComponent + BaseActivityComponent.class //1111111111 subComponent=BaseActivityComponent }) -public abstract class MainModuleAllActivityModule { - /** - * BaseActivity <- BaseMVPActivity 这样的继承关系就好了 - *

- * 1 BaseActivity: 不要MVP模式,也不用DI 依赖注入(少写两行代码)就用这个吧 - *

- * 2 BaseMVPActivity 要MVP 要DI ,全局的依赖注入 - */ +public abstract class MainModuleAllActivityModule { //2222222 新建了一个Activity 的并且需要inject 的只需要添加两行代码 DefaultActivityModule 适用于只要全局Module 中的内容 + + //要是能不声明就更好了,有点像Manifest 中的配置文件 @ActivityScope @ContributesAndroidInjector(modules = DefaultActivityModule.class) abstract ModuleMainLauncherActivity moduleMainLauncherActivity(); @@ -64,12 +59,22 @@ public abstract class MainModuleAllActivityModule { @ContributesAndroidInjector(modules = DefaultActivityModule.class) abstract MeFragment meFragmentInjector(); - @ActivityScope @ContributesAndroidInjector(modules = DefaultActivityModule.class) abstract NewsFragmentShell meFragmentxxInjector(); -// Pro-tip: If your subcomponent and its builder have no other methods or supertypes than the ones mentioned in step #2, you can use @ContributesAndroidInjector to generate them for you. Instead of steps 2 and 3, add an abstract module method that returns your activity, annotate it with @ContributesAndroidInjector, and specify the modules you want to install into the subcomponent. If the subcomponent needs scopes, apply the scope annotations to the method as well. +// More:https://google.github.io/dagger//android.html + +// If your subcomponent and its builder have no other methods or supertypes than the ones mentioned in step #2, +// you can use @ContributesAndroidInjector to generate them for you. Instead of steps 2 and 3, add an abstract +// module method that returns your activity, annotate it with @ContributesAndroidInjector, and specify the modules +// you want to install into the subcomponent. If the subcomponent needs scopes, +// apply the scope annotations to the method as well. +// +// @ActivityScope +// @ContributesAndroidInjector(modules = { /* modules to install into the subcomponent */ }) +// abstract YourActivity contributeYourActivityInjector(); + } diff --git a/module_news/NewsKeyStore b/module_news/NewsKeyStore new file mode 100644 index 0000000..2972892 Binary files /dev/null and b/module_news/NewsKeyStore differ diff --git a/module_news/build.gradle b/module_news/build.gradle index 5913dbf..28509b2 100644 --- a/module_news/build.gradle +++ b/module_news/build.gradle @@ -16,8 +16,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 - versionName "1.0" + versionCode 2 + versionName "1.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" //配置使用ARouter @@ -34,8 +34,19 @@ android { } + signingConfigs { + anylifezlbConfig { + storeFile file("NewsKeyStore") + storePassword "NewsKeyStore" + keyAlias "NewsKeyStore" + keyPassword "NewsKeyStore" + } + } + + buildTypes { release { + signingConfig signingConfigs.anylifezlbConfig minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } diff --git a/module_news/src/main/java/com/zenglb/framework/news/NewsWebActivity.java b/module_news/src/main/java/com/zenglb/framework/news/NewsWebActivity.java index 23bc153..18ca246 100755 --- a/module_news/src/main/java/com/zenglb/framework/news/NewsWebActivity.java +++ b/module_news/src/main/java/com/zenglb/framework/news/NewsWebActivity.java @@ -18,7 +18,6 @@ public class NewsWebActivity extends BaseWebViewActivity { private AdView mAdView; - @Override protected int getLayoutId() { return R.layout.activity_news_webview; diff --git a/module_news/src/main/java/com/zenglb/framework/news/dagger/NewsModuleAllActivityModule.java b/module_news/src/main/java/com/zenglb/framework/news/dagger/NewsModuleAllActivityModule.java index 239be54..ad22ddd 100644 --- a/module_news/src/main/java/com/zenglb/framework/news/dagger/NewsModuleAllActivityModule.java +++ b/module_news/src/main/java/com/zenglb/framework/news/dagger/NewsModuleAllActivityModule.java @@ -1,5 +1,6 @@ package com.zenglb.framework.news.dagger; +import com.zenglb.framework.news.handylife.ItIsATestModule; import com.zenglb.framework.news.handylife.NewsPackageActivity; import com.zenglb.framework.news.handylife.NewsFragment; import com.zenglb.framework.news.handylife.NewsPackageFragment; @@ -27,13 +28,6 @@ }) public abstract class NewsModuleAllActivityModule { - /** - * BaseActivity <- BaseMVPActivity 这样的继承关系就好了 - * - * 1 BaseActivity: 不要MVP模式,也不用DI 依赖注入(少写两行代码)就用这个吧 - * - * 2 BaseMVPActivity 要MVP 要DI ,全局的依赖注入 - */ //2222222 新建了一个Activity 的并且需要inject 的只需要添加两行代码 DefaultActivityModule 适用于只要全局Module 中的内容 @@ -48,7 +42,7 @@ public abstract class NewsModuleAllActivityModule { @ActivityScope - @ContributesAndroidInjector(modules = DefaultActivityModule.class) + @ContributesAndroidInjector(modules = ItIsATestModule.class) abstract NewsPackageActivity newsPackageActivityInjector(); diff --git a/module_news/src/main/java/com/zenglb/framework/news/dagger/NewsModuleComponent.java b/module_news/src/main/java/com/zenglb/framework/news/dagger/NewsModuleComponent.java index 2a885a8..3ed2153 100644 --- a/module_news/src/main/java/com/zenglb/framework/news/dagger/NewsModuleComponent.java +++ b/module_news/src/main/java/com/zenglb/framework/news/dagger/NewsModuleComponent.java @@ -10,13 +10,13 @@ import dagger.android.support.AndroidSupportInjectionModule; /** - * 全局的单例的东西提到这里来,比如SharedPrefenced,DaoSession 等等 ! - *

+ * 全局的单例的东西提到这里来,比如SP,DaoSession 等等 ! + * * Created by anylife.zlb@gmail.com on 2018/1/11. */ @Singleton @Component(modules = { - BaseGlobalModule.class, //全局的Module,要确保提供的对象是全局唯一的 + BaseGlobalModule.class, //全局的Module,要确保提供的对象是全局唯一的 AndroidInjectionModule.class, //在应用程序的MainComponent(application 中inject了)中,注入AndroidInjectionModule, // 以确保Android的类(Activity、Fragment、Service、BroadcastReceiver及ContentProvider等)可以绑定。 @@ -24,13 +24,13 @@ AndroidSupportInjectionModule.class, //使用的Fragment 是V4 包中的?不然就只需要AndroidInjectionModule - // - NewsModuleAllActivityModule.class, //减少模版代码,需要依赖注入的只需要添加两行代码就好了 - NewsGlobalModule.class, // + NewsModuleAllActivityModule.class, //减少模版代码,需要依赖注入的只需要添加两行代码就好了 + NewsGlobalModule.class, }) -//YourApplicationComponent + +//YourModuleApplicationComponent public interface NewsModuleComponent { void inject(BaseApplication application); diff --git a/module_news/src/main/java/com/zenglb/framework/news/handylife/ItIsATestModule.java b/module_news/src/main/java/com/zenglb/framework/news/handylife/ItIsATestModule.java new file mode 100644 index 0000000..abfd901 --- /dev/null +++ b/module_news/src/main/java/com/zenglb/framework/news/handylife/ItIsATestModule.java @@ -0,0 +1,22 @@ +package com.zenglb.framework.news.handylife; + +import dagger.Module; +import dagger.Provides; + + +/** + * 在 {@link NewsPackageActivity } 中测试使用 ! + * 测试使用 + * + */ +@Module +public class ItIsATestModule { + + @Provides + String provideName() { + return "Hello Kitty,It is a Test Module String"; // + } + + + +} diff --git a/module_news/src/main/java/com/zenglb/framework/news/handylife/NewsPackageActivity.java b/module_news/src/main/java/com/zenglb/framework/news/handylife/NewsPackageActivity.java index 4ddf97f..02f28ce 100644 --- a/module_news/src/main/java/com/zenglb/framework/news/handylife/NewsPackageActivity.java +++ b/module_news/src/main/java/com/zenglb/framework/news/handylife/NewsPackageActivity.java @@ -5,18 +5,24 @@ import com.zenglb.framework.news.R; import com.zlb.base.BaseActivity; import com.zlb.base.BaseMVPActivity; + +import javax.inject.Inject; + import component.android.com.component_base.ComponentServiceFactory; import component.android.com.component_base.base.IFragmentService; /** - * Module_news 模块调试的时候包装NewsFragment + * 仅仅是调试的时候使用,没有实际的用途 * - * NewsFragment 实际上是在MainBotNavi 中被使用 * */ public class NewsPackageActivity extends BaseMVPActivity { + @Inject + String testNameStr; + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/module_news/src/main/java/com/zenglb/framework/news/handylife/NewsRepository.java b/module_news/src/main/java/com/zenglb/framework/news/handylife/NewsRepository.java index ed2d4be..f3668a3 100644 --- a/module_news/src/main/java/com/zenglb/framework/news/handylife/NewsRepository.java +++ b/module_news/src/main/java/com/zenglb/framework/news/handylife/NewsRepository.java @@ -27,10 +27,6 @@ public NewsRepository() { } - public NewsRepository(NewsApiService apiService) { - this.apiService = apiService; - } - /** * getHandyLifeData from http server diff --git a/module_news/src/main/java/debug/NewsApplication.java b/module_news/src/main/java/debug/NewsApplication.java index 69429be..8ee2e25 100644 --- a/module_news/src/main/java/debug/NewsApplication.java +++ b/module_news/src/main/java/debug/NewsApplication.java @@ -18,12 +18,10 @@ public void onCreate() { super.onCreate(); login(); - //Fragment 组件化注册®️ ComponentServiceFactory.getInstance(this) .setNewsFragmentService(new NewsFragmentService()); - } @@ -36,10 +34,14 @@ private void login() { } + /** + * 配置好依赖注入 + * + */ @Override protected void injectApp() { DaggerNewsModuleComponent.builder() - .baseGlobalModule(new BaseGlobalModule(this)) + .baseGlobalModule(new BaseGlobalModule(this)) //这一行是把Base中的 .build() .inject(this); } diff --git a/module_news/src/main/java/debug/NewsLauncherActivity.java b/module_news/src/main/java/debug/NewsLauncherActivity.java index 594c4f8..7054a61 100644 --- a/module_news/src/main/java/debug/NewsLauncherActivity.java +++ b/module_news/src/main/java/debug/NewsLauncherActivity.java @@ -69,7 +69,6 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.launcher_layout); // Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 - MobileAds.initialize(this, "ca-app-pub-8621230724267558~7770389405"); mAdView = findViewById(R.id.adView); @@ -108,12 +107,13 @@ public void onAdClosed() { // Code to be executed when the user is about to return // to the app after tapping on an ad. int a=1; - } + }); UiHandler.sendEmptyMessageDelayed(FINISH_LAUNCHER, 3000); //测试内存泄漏,只为测试. + } diff --git a/module_note/.gitignore b/module_note/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/module_note/.gitignore @@ -0,0 +1 @@ +/build diff --git a/module_note/build.gradle b/module_note/build.gradle new file mode 100644 index 0000000..7cd6994 --- /dev/null +++ b/module_note/build.gradle @@ -0,0 +1,36 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + + + + defaultConfig { + applicationId "com.zenglb.framework.module_note" + minSdkVersion 21 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'com.android.support:appcompat-v7:28.0.0-alpha1' + implementation 'com.android.support.constraint:constraint-layout:1.1.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/module_note/proguard-rules.pro b/module_note/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/module_note/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/module_note/src/androidTest/java/com/zenglb/framework/module_note/ExampleInstrumentedTest.java b/module_note/src/androidTest/java/com/zenglb/framework/module_note/ExampleInstrumentedTest.java new file mode 100644 index 0000000..5abfc5e --- /dev/null +++ b/module_note/src/androidTest/java/com/zenglb/framework/module_note/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.zenglb.framework.module_note; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.zenglb.framework.module_note", appContext.getPackageName()); + } +} diff --git a/module_note/src/main/AndroidManifest.xml b/module_note/src/main/AndroidManifest.xml new file mode 100644 index 0000000..e235574 --- /dev/null +++ b/module_note/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/module_note/src/main/java/com/zenglb/framework/module_note/TestActivity.java b/module_note/src/main/java/com/zenglb/framework/module_note/TestActivity.java new file mode 100644 index 0000000..16d3029 --- /dev/null +++ b/module_note/src/main/java/com/zenglb/framework/module_note/TestActivity.java @@ -0,0 +1,136 @@ +package com.zenglb.framework.module_note; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; + +import com.zenglb.framework.module_note.test.DynamicProxy; +import com.zenglb.framework.module_note.test.Sell; +import com.zenglb.framework.module_note.test.Vendor; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * 感觉做一些不想分享的笔记也会很有意思的啊 + *

+ * 假如没能盈利可以最后做成离线版本吧 + *

+ * 数据库要加密,内容也要加密,换手机支持离线道出数据 ! + *

+ * Material Design 吧 + */ +public class TestActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test); + + +// //创建中介类实例 +// DynamicProxy inter = new DynamicProxy(new Vendor()); +// +// //加上这句将会产生一个$Proxy0.class文件,这个文件即为动态生成的代理类文件 +// System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); +// +// //获取代理类实例sell +// Sell sell = (Sell) (Proxy.newProxyInstance(Sell.class.getClassLoader(), new Class[]{Sell.class}, inter)); +// +// //通过代理类对象调用代理类方法,实际上会转到invoke方法调用 +// sell.sell(); +// sell.ad(); + + + /** + * 动态代理,拦截处理器 + * 所有的请求都可以添加自定义的行为 + * + * + * + */ + // 1. 首先实现一个InvocationHandler,方法调用会被转发到该类的invoke()方法。 + Sell sell = (Sell) Proxy.newProxyInstance( + Sell.class.getClassLoader(), //2.类加载器 + new Class[]{Sell.class}, //3.代理需要实现的类,要有多个 + new InvocationHandler() { //4.方法调用的实际处理者 + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + // If the method is a method from Object then defer to normal invocation. + Log.e("HHHH", "Before"); + + return method.invoke(new Vendor(), args); + } + }); + + + //得到了 + sell.sell(); + sell.ad(); + + +// 上述代码的关键是Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler handler)方法,该方法会根据指定的参数动态创建代理对象。三个参数的意义如下: +// +// loader,指定代理对象的类加载器; +// interfaces,代理对象需要实现的接口,可以同时指定多个接口; +// handler,方法调用的实际处理者,代理对象的方法调用都会转发到这里(*注意1)。 +// newProxyInstance()会返回一个实现了指定接口的代理对象,对该对象的所有方法调用都会转发给InvocationHandler.invoke()方法。理解上述代码需要对Java反射机制有一定了解。动态代理神奇的地方就是: +// +// 代理对象是在程序运行时产生的,而不是编译期; +// 对代理对象的所有接口方法调用都会转发到InvocationHandler.invoke()方法,在invoke()方法里我们可以加入任何逻辑,比如修改方法参数,加入日志功能、安全检查功能等;之后我们通过某种方式执行真正的方法体,示例中通过反 射调用了Hello对象的相应方法,还可以通过RPC调用远程方法。 + + + +// //太慢了。跑了一晚上都没有跑出结果来 +// new Thread(new Runnable() { +// @Override +// public void run() { +// hahah(); +// } +// }).start(); + + + } + + + /** + * 两个质数相乘=707829217。求之 ? + */ + private void hahah() { + for (int x = 3; x < 707829217; x++) { + int flag1 = 0; + for (int i = 2; i < x / 2; i++) { + if (x % i == 0) { + flag1 = 1; + break; + } + } + if (flag1 == 0) { + for (int y = 3; y < 707829217; y++) { + int flag2 = 0; + for (int j = 2; j < y / 2; j++) { + if (y % j == 0) { + flag2 = 1; + break; + } + } + if (flag2 == 0) { + Log.d("AAAAA", "X=" + x + " Y=" + y); + + if (x * y == 707829217) { + Log.e("AAAAARFRT", "X=" + x + " Y=" + y); + return; + } + } + } + } + } + } + + +} + + + diff --git a/module_note/src/main/java/com/zenglb/framework/module_note/test/BusinessAgent.java b/module_note/src/main/java/com/zenglb/framework/module_note/test/BusinessAgent.java new file mode 100644 index 0000000..6bac145 --- /dev/null +++ b/module_note/src/main/java/com/zenglb/framework/module_note/test/BusinessAgent.java @@ -0,0 +1,23 @@ +package com.zenglb.framework.module_note.test; + + +/** + * 代理类,静态代理类 + * + */ +public class BusinessAgent implements Sell{ + private Sell vendor; + + public BusinessAgent(Sell vendor){ + this.vendor = vendor; + } + + public void sell() { + vendor.sell(); + } + + public void ad() { + vendor.ad(); + } + +} diff --git a/module_note/src/main/java/com/zenglb/framework/module_note/test/DynamicProxy.java b/module_note/src/main/java/com/zenglb/framework/module_note/test/DynamicProxy.java new file mode 100644 index 0000000..8095df7 --- /dev/null +++ b/module_note/src/main/java/com/zenglb/framework/module_note/test/DynamicProxy.java @@ -0,0 +1,34 @@ +package com.zenglb.framework.module_note.test; + +import android.util.Log; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * 动态代理类 + * + * + * + */ +public class DynamicProxy implements InvocationHandler { + String Tag=DynamicProxy.class.getSimpleName(); + + //obj为委托类对象; + private Object obj; + + public DynamicProxy(Object obj) { + this.obj = obj; + } + + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Log.e(Tag,"Before"); + Object result = method.invoke(obj, args); + Log.e(Tag,"After"); + return result; + } + + +} diff --git a/module_note/src/main/java/com/zenglb/framework/module_note/test/Sell.java b/module_note/src/main/java/com/zenglb/framework/module_note/test/Sell.java new file mode 100644 index 0000000..9a47439 --- /dev/null +++ b/module_note/src/main/java/com/zenglb/framework/module_note/test/Sell.java @@ -0,0 +1,13 @@ +package com.zenglb.framework.module_note.test; + + +/** + * 下面我们用Vendor类代表生产厂家,BusinessAgent类代表微商代理, + * 来介绍下静态代理的简单实现,委托类和代理类都实现了Sell接口 + * Sell接口的定义如下 + * + */ +public interface Sell { + void sell(); + void ad(); +} diff --git a/module_note/src/main/java/com/zenglb/framework/module_note/test/Vendor.java b/module_note/src/main/java/com/zenglb/framework/module_note/test/Vendor.java new file mode 100644 index 0000000..87af8dd --- /dev/null +++ b/module_note/src/main/java/com/zenglb/framework/module_note/test/Vendor.java @@ -0,0 +1,22 @@ +package com.zenglb.framework.module_note.test; + +import android.util.Log; + +/** + * 生成厂家,委托类 + * + */ +public class Vendor implements Sell { + String Tag=Vendor.class.getSimpleName(); + + + @Override + public void sell() { + Log.e(Tag,"in sell method"); + } + + @Override + public void ad() { + Log.e(Tag,"in ad method"); + } +} diff --git a/module_note/src/main/res/drawable-v24/ic_launcher_foreground.xml b/module_note/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/module_note/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/module_note/src/main/res/drawable/ic_launcher_background.xml b/module_note/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/module_note/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_note/src/main/res/layout/activity_test.xml b/module_note/src/main/res/layout/activity_test.xml new file mode 100644 index 0000000..15e095c --- /dev/null +++ b/module_note/src/main/res/layout/activity_test.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/module_note/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/module_note/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/module_note/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/module_note/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/module_note/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/module_note/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/module_note/src/main/res/mipmap-hdpi/ic_launcher.png b/module_note/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..898f3ed Binary files /dev/null and b/module_note/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/module_note/src/main/res/mipmap-hdpi/ic_launcher_round.png b/module_note/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..dffca36 Binary files /dev/null and b/module_note/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/module_note/src/main/res/mipmap-mdpi/ic_launcher.png b/module_note/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..64ba76f Binary files /dev/null and b/module_note/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/module_note/src/main/res/mipmap-mdpi/ic_launcher_round.png b/module_note/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..dae5e08 Binary files /dev/null and b/module_note/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/module_note/src/main/res/mipmap-xhdpi/ic_launcher.png b/module_note/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..e5ed465 Binary files /dev/null and b/module_note/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/module_note/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/module_note/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..14ed0af Binary files /dev/null and b/module_note/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/module_note/src/main/res/mipmap-xxhdpi/ic_launcher.png b/module_note/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..b0907ca Binary files /dev/null and b/module_note/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/module_note/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/module_note/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..d8ae031 Binary files /dev/null and b/module_note/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/module_note/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/module_note/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..2c18de9 Binary files /dev/null and b/module_note/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/module_note/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/module_note/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..beed3cd Binary files /dev/null and b/module_note/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/module_note/src/main/res/values/colors.xml b/module_note/src/main/res/values/colors.xml new file mode 100644 index 0000000..69b2233 --- /dev/null +++ b/module_note/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #008577 + #00574B + #D81B60 + diff --git a/module_note/src/main/res/values/strings.xml b/module_note/src/main/res/values/strings.xml new file mode 100644 index 0000000..b54f6ee --- /dev/null +++ b/module_note/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + module_note + diff --git a/module_note/src/main/res/values/styles.xml b/module_note/src/main/res/values/styles.xml new file mode 100644 index 0000000..5885930 --- /dev/null +++ b/module_note/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/module_note/src/test/java/com/zenglb/framework/module_note/ExampleUnitTest.java b/module_note/src/test/java/com/zenglb/framework/module_note/ExampleUnitTest.java new file mode 100644 index 0000000..98d9b8c --- /dev/null +++ b/module_note/src/test/java/com/zenglb/framework/module_note/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.zenglb.framework.module_note; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 6b926e9..e4298f6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':baselib', ':module_main' , 'module_news','component-base' \ No newline at end of file +include ':app', ':baselib', ':module_main', ':module_note' , 'module_news','component-base' \ No newline at end of file