diff --git a/.gitignore b/.gitignore index eef2d45..63fc54f 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,6 @@ captures/ .idea/vcs.xml .idea/libraries + # Keystore files *.jks diff --git a/README.md b/README.md index ed413cd..438a057 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ + @@ -14,12 +15,18 @@ Android项目组件化示例代码 **Android组件化方案**:http://blog.csdn.net/guiying712/article/details/55213884 -Android组件化方案中的路由使用了ActivityRouter,但是因为ActivityRouter对于初学者不太友好, -总是出现莫名其妙的错误,因此现在的 AndroidModulePattern 已经改为使用 阿里ARouter作为路由。 +**Android组件化之终极方案**:http://blog.csdn.net/guiying712/article/details/78057120 + +1. 现在的 AndroidModulePattern 使用 阿里ARouter作为路由; + +2. Android组件化方案已经支持 **Fragment组件化**,使用方法请下载Demo查看; + +3. 本项目已适配Android Studio 3.0.1版本(Google仓库会带来一定影响) + ## 集成开发模式和组件开发模式转换 -**1、首先打开Android项目的 gradle.properties 文件,然后将 isModule 改为你需要的开发模式, +**1、首先打开Android项目的 gradle.properties 文件,然后将 isModule 改为你需要的开发模式(true/false), 然后点击 "Sync Project" 按钮同步项目;** **2、![Image](/screenshots/develper.PNG) 在运行之前,请先按照图中选择一个能够运行的组件;** @@ -31,6 +38,7 @@ Android组件化方案中的路由使用了ActivityRouter,但是因为Activity 1. 配置整个项目的Gradle脚本,例如 混淆、签名等; 2. app组件中可以初始化全局的库,例如Lib.init(this); 3. 添加 multiDex 功能 +4. 业务组件管理(组装); ### main组件功能(业务组件): 1. 声明应用的launcherActivity----->android.intent.category.LAUNCHER; @@ -61,4 +69,4 @@ Android组件化方案中的路由使用了ActivityRouter,但是因为Activity distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/build.gradle b/build.gradle index 3874a63..40fe932 100644 --- a/build.gradle +++ b/build.gradle @@ -1,61 +1,38 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - repositories { - jcenter() - mavenCentral() - } - + apply from: 'versions.gradle' + addRepos(repositories) dependencies { - //classpath "com.android.tools.build:gradle:$localGradlePluginVersion" - //$localGradlePluginVersion是gradle.properties中的数据 - classpath "com.android.tools.build:gradle:$localGradlePluginVersion" + /* classpath deps.android_gradle_plugin*/ + classpath deps.android_gradle_plugin + classpath deps.kotlin.plugin + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files } } allprojects { - repositories { - jcenter() - mavenCentral() - //Add the JitPack repository - maven { url "https://jitpack.io" } - //支持arr包 - flatDir { - dirs 'libs' + addRepos(repositories) + // Android dependency 'com.android.support:design' has different version for the compile (25.3.1) and runtime (25.4.0) classpath. + // You should manually set the same version via DependencyResolution + subprojects { + project.configurations.all { + resolutionStrategy.eachDependency { details -> + if (details.requested.group == 'com.android.support' + && !details.requested.name.contains('multidex')) { + details.useVersion "27.0.2" + } + } } } + + // 组件缓存更新时间设置(默认每次build都更新) + configurations.all { + resolutionStrategy.cacheChangingModulesFor 0, 'minutes' + } } task clean(type: Delete) { delete rootProject.buildDir -} - -// Define versions in a single place -//时间:2017.2.13;每次修改版本号都要添加修改时间 -ext { - // Sdk and tools - //localBuildToolsVersion是gradle.properties中的数据 - buildToolsVersion = localBuildToolsVersion - compileSdkVersion = 25 - minSdkVersion = 16 - targetSdkVersion = 25 - versionCode = 1 - versionName = "1.0" - javaVersion = JavaVersion.VERSION_1_8 - - // App dependencies version - supportLibraryVersion = "25.3.1" - retrofitVersion = "2.1.0" - glideVersion = "3.7.0" - loggerVersion = "1.15" - eventbusVersion = "3.0.0" - gsonVersion = "2.8.0" - photoViewVersion = "2.0.0" - - //检查时间:2017.6.6 - annotationProcessor = "1.0.3" - routerVersion = "1.2.1.1" - easyRecyclerVersion = "4.4.0" - cookieVersion = "v1.0.1" - toastyVersion = "1.1.3" -} +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index d817325..9b51cd5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,10 +18,8 @@ org.gradle.jvmargs=-Xmx2048m org.gradle.daemon=true org.gradle.configureondemand=true org.gradle.parallel=true -# ΪԶ(ΪÿĵԻһ) -localBuildToolsVersion=25.0.3 # ֵһAndroidStudio汾һ -localGradlePluginVersion=2.3.3 +localGradlePluginVersion=3.0.1 # ÿθġisModuleֵҪ "Sync Project" ť # isModuleǡɿģʽ͡ģʽл diff --git a/keystore.properties b/keystore.properties new file mode 100644 index 0000000..dabd93e --- /dev/null +++ b/keystore.properties @@ -0,0 +1,4 @@ +storePassword=guiying712 +keyPassword=guiying712 +keyAlias=guiying712 +storeFile=/mykey.jks \ No newline at end of file diff --git a/lib_common/build.gradle b/lib_common/build.gradle index 1ec98ca..87eb2af 100644 --- a/lib_common/build.gradle +++ b/lib_common/build.gradle @@ -1,37 +1,76 @@ apply plugin: 'com.android.library' android { - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - + compileSdkVersion build_versions.target_sdk defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode rootProject.ext.versionCode - versionName rootProject.ext.versionName + minSdkVersion build_versions.min_sdk + targetSdkVersion build_versions.target_sdk + versionCode 1 + versionName "1.0" + } + + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + buildTypes { + release { + buildConfigField "boolean", "LOG_DEBUG", "true" + zipAlignEnabled false + shrinkResources false + minifyEnabled false + debuggable true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } } + } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - //Android Support - compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion" - compile "com.android.support:design:$rootProject.supportLibraryVersion" - compile "com.android.support:percent:$rootProject.supportLibraryVersion" - //网络请求相关 - compile "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion" - compile "com.squareup.retrofit2:retrofit-mock:$rootProject.retrofitVersion" - compile "com.github.franmontiel:PersistentCookieJar:$rootProject.cookieVersion" - //稳定的 - compile "com.github.bumptech.glide:glide:$rootProject.glideVersion" - compile "com.orhanobut:logger:$rootProject.loggerVersion" - compile "org.greenrobot:eventbus:$rootProject.eventbusVersion" - compile "com.google.code.gson:gson:$rootProject.gsonVersion" - compile "com.github.chrisbanes:PhotoView:$rootProject.photoViewVersion" - - compile "com.jude:easyrecyclerview:$rootProject.easyRecyclerVersion" - compile "com.github.GrenderG:Toasty:$rootProject.toastyVersion" + api fileTree(include: ['*.jar'], dir: 'libs') + // Support libraries + api deps.support.app_compat + api deps.support.v4 + api deps.support.v13 + api deps.support.design + api deps.support.cardview + api deps.support.percent + api deps.support.recyclerview + api deps.constraint_layout + + // RxJava and retrofit + api deps.rx_android + api deps.rxjava2 + api deps.retrofit.runtime + api deps.retrofit.gson + api deps.persistent_cookie + + //Dagger + api deps.dagger.runtime + api deps.dagger.android + api deps.dagger.android_support + + // other + api deps.kotlin.stdlib + api deps.event_bus + api deps.gson + api deps.permission + api deps.utils + api deps.glide + + //view + api deps.photo_view + api deps.easy_recycler + api deps.material_dialog + api deps.logger + api deps.toasty //router - compile "com.alibaba:arouter-api:$rootProject.routerVersion" + api deps.arouter_api + + //annotationProcessor + annotationProcessor deps.dagger.android_support_compiler + annotationProcessor deps.dagger.compiler } diff --git a/lib_common/src/main/AndroidManifest.xml b/lib_common/src/main/AndroidManifest.xml index 5b1cff1..8039311 100644 --- a/lib_common/src/main/AndroidManifest.xml +++ b/lib_common/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.guiying.module.common"> @@ -16,7 +16,7 @@ diff --git a/lib_common/src/main/java/com/guiying/common/base/BaseActivity.java b/lib_common/src/main/java/com/guiying/common/base/BaseActivity.java deleted file mode 100644 index 5e9b3f5..0000000 --- a/lib_common/src/main/java/com/guiying/common/base/BaseActivity.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.guiying.common.base; - -import android.os.Bundle; -import android.support.annotation.IdRes; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.view.View; - -import com.guiying.common.R; - -/** - *

Activity基类

- * - * @author 2016/12/2 17:33 - * @version V1.0.0 - * @name BaseActivity - */ -public abstract class BaseActivity extends AppCompatActivity { - - /** - * Setup the toolbar. - * - * @param toolbar toolbar - * @param hideTitle 是否隐藏Title - */ - protected void setupToolBar(Toolbar toolbar, boolean hideTitle) { - setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back); - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setDisplayShowHomeEnabled(true); - if (hideTitle) { - //隐藏Title - actionBar.setDisplayShowTitleEnabled(false); - } - } - } - - - /** - * 封装的findViewByID方法 - */ - @SuppressWarnings("unchecked") - protected T $(@IdRes int id) { - return (T) super.findViewById(id); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - BaseApplication.getIns().addActivity(this); - } - - - @Override - protected void onDestroy() { - super.onDestroy(); - BaseApplication.getIns().finishActivity(this); - } - - @Override - public boolean onSupportNavigateUp() { - onBackPressed(); - return true; - } - -} diff --git a/lib_common/src/main/java/com/guiying/common/base/BasePresenter.java b/lib_common/src/main/java/com/guiying/common/base/BasePresenter.java deleted file mode 100644 index c05c925..0000000 --- a/lib_common/src/main/java/com/guiying/common/base/BasePresenter.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.guiying.common.base; - -public interface BasePresenter { - - void start(); - -} diff --git a/lib_common/src/main/java/com/guiying/common/base/BaseView.java b/lib_common/src/main/java/com/guiying/common/base/BaseView.java deleted file mode 100644 index debd151..0000000 --- a/lib_common/src/main/java/com/guiying/common/base/BaseView.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.guiying.common.base; - -public interface BaseView { - - void setPresenter(T presenter); - -} diff --git a/lib_common/src/main/java/com/guiying/common/base/BaseActionBarActivity.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseActionBarActivity.java similarity index 80% rename from lib_common/src/main/java/com/guiying/common/base/BaseActionBarActivity.java rename to lib_common/src/main/java/com/guiying/module/common/base/BaseActionBarActivity.java index a14d93d..85c8570 100644 --- a/lib_common/src/main/java/com/guiying/common/base/BaseActionBarActivity.java +++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseActionBarActivity.java @@ -1,17 +1,11 @@ -/* - * @ProjectName: ISMS_Petrel_MCU - * @Copyright: 2017 HangZhou Hikvision System Technology Co., Ltd. All Right Reserved. - * @address: http://www.hikvision.com - * @Description: 本内容仅限于杭州海康威视系统技术公有限司内部使用,禁止转发. - */ - -package com.guiying.common.base; +package com.guiying.module.common.base; import android.os.Bundle; +import android.support.annotation.Keep; import android.support.annotation.StringRes; import android.support.v7.app.ActionBar; -import com.guiying.common.R; +import com.guiying.module.common.R; /** * BaseActionBarActivity继承于BaseActivity,封装了actionBar的逻辑; @@ -22,6 +16,7 @@ * @version V1.2.0 * @name BaseActionBarActivity */ +@Keep public abstract class BaseActionBarActivity extends BaseActivity { /*默认的ActionBar*/ diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseActivity.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseActivity.java new file mode 100644 index 0000000..32ffebe --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseActivity.java @@ -0,0 +1,157 @@ +package com.guiying.module.common.base; + +import android.os.Bundle; +import android.support.annotation.IdRes; +import android.support.annotation.Keep; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +import com.guiying.module.common.R; +import com.guiying.module.common.utils.Utils; + +/** + *

Activity基类

+ * + * @author 2016/12/2 17:33 + * @version V1.0.0 + * @name BaseActivity + */ +@Keep +public abstract class BaseActivity extends AppCompatActivity { + + + /** + * 封装的findViewByID方法 + */ + @SuppressWarnings("unchecked") + protected T $(@IdRes int id) { + return (T) super.findViewById(id); + } + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ViewManager.getInstance().addActivity(this); + } + + + @Override + protected void onDestroy() { + super.onDestroy(); + ViewManager.getInstance().finishActivity(this); + } + + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; + } + + + /** + * Setup the toolbar. + * + * @param toolbar toolbar + * @param hideTitle 是否隐藏Title + */ + protected void setupToolBar(Toolbar toolbar, boolean hideTitle) { + setSupportActionBar(toolbar); + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back); + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setDisplayShowHomeEnabled(true); + if (hideTitle) { + //隐藏Title + actionBar.setDisplayShowTitleEnabled(false); + } + } + } + + + /** + * 添加fragment + * + * @param fragment + * @param frameId + */ + protected void addFragment(BaseFragment fragment, @IdRes int frameId) { + Utils.checkNotNull(fragment); + getSupportFragmentManager().beginTransaction() + .add(frameId, fragment, fragment.getClass().getSimpleName()) + .addToBackStack(fragment.getClass().getSimpleName()) + .commitAllowingStateLoss(); + + } + + + /** + * 替换fragment + * @param fragment + * @param frameId + */ + protected void replaceFragment(BaseFragment fragment, @IdRes int frameId) { + Utils.checkNotNull(fragment); + getSupportFragmentManager().beginTransaction() + .replace(frameId, fragment, fragment.getClass().getSimpleName()) + .addToBackStack(fragment.getClass().getSimpleName()) + .commitAllowingStateLoss(); + + } + + + /** + * 隐藏fragment + * @param fragment + */ + protected void hideFragment(BaseFragment fragment) { + Utils.checkNotNull(fragment); + getSupportFragmentManager().beginTransaction() + .hide(fragment) + .commitAllowingStateLoss(); + + } + + + /** + * 显示fragment + * @param fragment + */ + protected void showFragment(BaseFragment fragment) { + Utils.checkNotNull(fragment); + getSupportFragmentManager().beginTransaction() + .show(fragment) + .commitAllowingStateLoss(); + + } + + + /** + * 移除fragment + * @param fragment + */ + protected void removeFragment(BaseFragment fragment) { + Utils.checkNotNull(fragment); + getSupportFragmentManager().beginTransaction() + .remove(fragment) + .commitAllowingStateLoss(); + + } + + + /** + * 弹出栈顶部的Fragment + */ + protected void popFragment() { + if (getSupportFragmentManager().getBackStackEntryCount() > 1) { + getSupportFragmentManager().popBackStack(); + } else { + finish(); + } + } + + +} diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseApplication.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseApplication.java new file mode 100644 index 0000000..5c183ee --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseApplication.java @@ -0,0 +1,71 @@ +package com.guiying.module.common.base; + +import android.app.Application; + +import com.guiying.module.common.utils.Utils; +import com.orhanobut.logger.LogLevel; +import com.orhanobut.logger.Logger; + +import java.util.List; + +/** + * 要想使用BaseApplication,必须在组件中实现自己的Application,并且继承BaseApplication; + * 组件中实现的Application必须在debug包中的AndroidManifest.xml中注册,否则无法使用; + * 组件的Application需置于java/debug文件夹中,不得放于主代码; + * 组件中获取Context的方法必须为:Utils.getContext(),不允许其他写法; + * + * @author 2016/12/2 17:02 + * @version V1.0.0 + * @name BaseApplication + */ +public class BaseApplication extends Application { + + public static final String ROOT_PACKAGE = "com.guiying.module"; + + private static BaseApplication sInstance; + + private List mAppDelegateList; + + + public static BaseApplication getIns() { + return sInstance; + } + + @Override + public void onCreate() { + super.onCreate(); + sInstance = this; + Logger.init("pattern").logLevel(LogLevel.FULL); + Utils.init(this); + mAppDelegateList = ClassUtils.getObjectsWithInterface(this, IApplicationDelegate.class, ROOT_PACKAGE); + for (IApplicationDelegate delegate : mAppDelegateList) { + delegate.onCreate(); + } + + } + + @Override + public void onTerminate() { + super.onTerminate(); + for (IApplicationDelegate delegate : mAppDelegateList) { + delegate.onTerminate(); + } + } + + + @Override + public void onLowMemory() { + super.onLowMemory(); + for (IApplicationDelegate delegate : mAppDelegateList) { + delegate.onLowMemory(); + } + } + + @Override + public void onTrimMemory(int level) { + super.onTrimMemory(level); + for (IApplicationDelegate delegate : mAppDelegateList) { + delegate.onTrimMemory(level); + } + } +} diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseFragment.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseFragment.java new file mode 100644 index 0000000..5ec3cb5 --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseFragment.java @@ -0,0 +1,104 @@ +package com.guiying.module.common.base; + +import android.content.Context; +import android.support.annotation.IdRes; +import android.support.annotation.Keep; +import android.support.v4.app.Fragment; + +import com.guiying.module.common.utils.Utils; + +/** + *

Fragment的基类

+ * + * @author 张华洋 + * @name BaseFragment + */ +@Keep +public abstract class BaseFragment extends Fragment { + + protected BaseActivity mActivity; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + this.mActivity = (BaseActivity) context; + } + + + /** + * 获取宿主Activity + * + * @return BaseActivity + */ + protected BaseActivity getHoldingActivity() { + return mActivity; + } + + + /** + * 添加fragment + * + * @param fragment + * @param frameId + */ + protected void addFragment(BaseFragment fragment, @IdRes int frameId) { + Utils.checkNotNull(fragment); + getHoldingActivity().addFragment(fragment, frameId); + + } + + + /** + * 替换fragment + * + * @param fragment + * @param frameId + */ + protected void replaceFragment(BaseFragment fragment, @IdRes int frameId) { + Utils.checkNotNull(fragment); + getHoldingActivity().replaceFragment(fragment, frameId); + } + + + /** + * 隐藏fragment + * + * @param fragment + */ + protected void hideFragment(BaseFragment fragment) { + Utils.checkNotNull(fragment); + getHoldingActivity().hideFragment(fragment); + } + + + /** + * 显示fragment + * + * @param fragment + */ + protected void showFragment(BaseFragment fragment) { + Utils.checkNotNull(fragment); + getHoldingActivity().showFragment(fragment); + } + + + /** + * 移除Fragment + * + * @param fragment + */ + protected void removeFragment(BaseFragment fragment) { + Utils.checkNotNull(fragment); + getHoldingActivity().removeFragment(fragment); + + } + + + /** + * 弹出栈顶部的Fragment + */ + protected void popFragment() { + getHoldingActivity().popFragment(); + } + +} diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BasePresenter.java b/lib_common/src/main/java/com/guiying/module/common/base/BasePresenter.java new file mode 100644 index 0000000..be56ad9 --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/base/BasePresenter.java @@ -0,0 +1,16 @@ +package com.guiying.module.common.base; + +import android.support.annotation.Keep; + +/** + *

Presenter的基类

+ * + * @author 张华洋 + * @name BasePresenter + */ +@Keep +public interface BasePresenter { + + void start(); + +} diff --git a/lib_common/src/main/java/com/guiying/module/common/base/BaseView.java b/lib_common/src/main/java/com/guiying/module/common/base/BaseView.java new file mode 100644 index 0000000..e1b0b21 --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/base/BaseView.java @@ -0,0 +1,17 @@ +package com.guiying.module.common.base; + + +import android.support.annotation.Keep; + +/** + *

View接口的基类

+ * + * @author 张华洋 + * @name BaseView + */ +@Keep +public interface BaseView { + + void setPresenter(T presenter); + +} diff --git a/lib_common/src/main/java/com/guiying/module/common/base/ClassUtils.java b/lib_common/src/main/java/com/guiying/module/common/base/ClassUtils.java new file mode 100644 index 0000000..7e65de6 --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/base/ClassUtils.java @@ -0,0 +1,296 @@ +package com.guiying.module.common.base; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.support.annotation.Keep; +import android.util.Log; + +import com.guiying.module.common.utils.Utils; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import dalvik.system.DexFile; + +/** + * Copy from galaxy sdk ${com.alibaba.android.galaxy.utils.ClassUtils} + * Scanner, find out class with any conditions, copy from google source code. + */ +@Keep +public class ClassUtils { + private static final String TAG = "ClassUtils"; + + private static final String EXTRACTED_NAME_EXT = ".classes"; + private static final String EXTRACTED_SUFFIX = ".zip"; + + private static final String SECONDARY_FOLDER_NAME = "code_cache" + File.separator + "secondary-dexes"; + + private static final String PREFS_FILE = "multidex.version"; + private static final String KEY_DEX_NUMBER = "dex.number"; + + private static final int VM_WITH_MULTIDEX_VERSION_MAJOR = 2; + private static final int VM_WITH_MULTIDEX_VERSION_MINOR = 1; + + private static SharedPreferences getMultiDexPreferences(Context context) { + return context.getSharedPreferences(PREFS_FILE, Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ? Context.MODE_PRIVATE : Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS); + } + + + /** + * 获取单一路径下所有实现了接口的类对象 + * + * @param context U know + * @param clazz 接口 + * @param path 包路径 + * @param U know + * @return 对象列表 + */ + public static List + getObjectsWithInterface(Context context, Class clazz, String path) { + List objectList = new ArrayList<>(); + try { + //找出所有路径中的类名,主要用于各个组件根包名一致的情况 + List classFileNames = getFileNameByPackageName(context, path); + + for (String className : classFileNames) { + Class aClass = Class.forName(className); + if (clazz.isAssignableFrom(aClass) && !clazz.equals(aClass) && !aClass.isInterface()) { + objectList.add((T) Class.forName(className).getConstructor().newInstance()); + } + } + + if (objectList.size() == 0) { + Log.e(TAG, "No files were found, check your configuration please!"); + } + } catch (Exception e) { + e.getStackTrace(); + Log.e(TAG, "getObjectsWithInterface error, " + e.getMessage()); + } + + return objectList; + } + + + /** + * 获取多路径下所有实现了接口的类对象 + * + * @param context U know + * @param clazz 接口 + * @param pathList 包路径列表 + * @param U know + * @return 对象列表 + */ + public static List getObjectsWithInterface(Context context, Class clazz, List pathList) { + List objectList = new ArrayList<>(); + try { + for (String path : pathList) { + //找出所有路径中的类名,主要用于各个组件根包名不一致的情况 + List classFileNames = getFileNameByPackageName(context, path); + + for (String className : classFileNames) { + Class aClass = Class.forName(className); + if (clazz.isAssignableFrom(aClass) && !clazz.equals(aClass) && !aClass.isInterface()) { + objectList.add((T) Class.forName(className).getConstructor().newInstance()); + } + } + } + + if (objectList.size() == 0) { + Log.e(TAG, "No files were found, check your configuration please!"); + } + } catch (Exception e) { + e.getStackTrace(); + Log.e(TAG, "getObjectsWithInterface error, " + e.getMessage()); + } + + return objectList; + } + + + /** + * 通过指定包名,扫描包下面包含的所有的ClassName + * + * @param context U know + * @param packageName 包名 + * @return 所有class的集合 + */ + public static List getFileNameByPackageName(Context context, String packageName) throws PackageManager.NameNotFoundException, IOException { + List classNames = new ArrayList<>(); + for (String path : getSourcePaths(context)) { + DexFile dexfile = null; + + try { + if (path.endsWith(EXTRACTED_SUFFIX)) { + //NOT use new DexFile(path), because it will throw "permission error in /data/dalvik-cache" + dexfile = DexFile.loadDex(path, path + ".tmp", 0); + } else { + dexfile = new DexFile(path); + } + Enumeration dexEntries = dexfile.entries(); + while (dexEntries.hasMoreElements()) { + String className = dexEntries.nextElement(); + if (className.contains(packageName)) { + classNames.add(className); + } + } + } catch (Throwable ignore) { + Log.e(TAG, "Scan map file in dex files made error.", ignore); + } finally { + if (null != dexfile) { + try { + dexfile.close(); + } catch (Throwable ignore) { + } + } + } + } + + Log.d(TAG, "Filter " + classNames.size() + " classes by packageName <" + packageName + ">"); + return classNames; + } + + /** + * get all the dex path + * + * @param context the application context + * @return all the dex path + * @throws PackageManager.NameNotFoundException Exception + * @throws IOException Exception + */ + public static List getSourcePaths(Context context) throws PackageManager.NameNotFoundException, IOException { + ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0); + File sourceApk = new File(applicationInfo.sourceDir); + + List sourcePaths = new ArrayList<>(); + sourcePaths.add(applicationInfo.sourceDir); //add the default apk path + + //the prefix of extracted file, ie: test.classes + String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT; + + //如果VM已经支持了MultiDex,就不要去Secondary Folder加载 Classesx.zip了,那里已经么有了 + //通过是否存在sp中的multidex.version是不准确的,因为从低版本升级上来的用户,是包含这个sp配置的 + if (!isVMMultidexCapable()) { + //the total dex numbers + int totalDexNumber = getMultiDexPreferences(context).getInt(KEY_DEX_NUMBER, 1); + File dexDir = new File(applicationInfo.dataDir, SECONDARY_FOLDER_NAME); + + for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) { + //for each dex file, ie: test.classes2.zip, test.classes3.zip... + String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX; + File extractedFile = new File(dexDir, fileName); + if (extractedFile.isFile()) { + sourcePaths.add(extractedFile.getAbsolutePath()); + //we ignore the verify zip part + } else { + throw new IOException("Missing extracted secondary dex file '" + extractedFile.getPath() + "'"); + } + } + } + + if (Utils.isAppDebug()) { + // Search instant run support only debuggable + sourcePaths.addAll(tryLoadInstantRunDexFile(applicationInfo)); + } + return sourcePaths; + } + + /** + * Get instant run dex path, used to catch the branch usingApkSplits=false. + */ + private static List tryLoadInstantRunDexFile(ApplicationInfo applicationInfo) { + List instantRunSourcePaths = new ArrayList<>(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && null != applicationInfo.splitSourceDirs) { + // add the splite apk, normally for InstantRun, and newest version. + instantRunSourcePaths.addAll(Arrays.asList(applicationInfo.splitSourceDirs)); + Log.d(TAG, "Found InstantRun support"); + } else { + try { + // This man is reflection from Google instant run sdk, he will tell me where the dex files go. + Class pathsByInstantRun = Class.forName("com.android.tools.fd.runtime.Paths"); + Method getDexFileDirectory = pathsByInstantRun.getMethod("getDexFileDirectory", String.class); + String instantRunDexPath = (String) getDexFileDirectory.invoke(null, applicationInfo.packageName); + + File instantRunFilePath = new File(instantRunDexPath); + if (instantRunFilePath.exists() && instantRunFilePath.isDirectory()) { + File[] dexFile = instantRunFilePath.listFiles(); + for (File file : dexFile) { + if (null != file && file.exists() && file.isFile() && file.getName().endsWith(".dex")) { + instantRunSourcePaths.add(file.getAbsolutePath()); + } + } + Log.d(TAG, "Found InstantRun support"); + } + + } catch (Exception e) { + Log.e(TAG, "InstantRun support error, " + e.getMessage()); + } + } + + return instantRunSourcePaths; + } + + /** + * Identifies if the current VM has a native support for multidex, meaning there is no need for + * additional installation by this library. + * + * @return true if the VM handles multidex + */ + private static boolean isVMMultidexCapable() { + boolean isMultidexCapable = false; + String vmName = null; + + try { + if (isYunOS()) { // YunOS需要特殊判断 + vmName = "'YunOS'"; + isMultidexCapable = Integer.valueOf(System.getProperty("ro.build.version.sdk")) >= 21; + } else { // 非YunOS原生Android + vmName = "'Android'"; + String versionString = System.getProperty("java.vm.version"); + if (versionString != null) { + Matcher matcher = Pattern.compile("(\\d+)\\.(\\d+)(\\.\\d+)?").matcher(versionString); + if (matcher.matches()) { + try { + int major = Integer.parseInt(matcher.group(1)); + int minor = Integer.parseInt(matcher.group(2)); + isMultidexCapable = (major > VM_WITH_MULTIDEX_VERSION_MAJOR) + || ((major == VM_WITH_MULTIDEX_VERSION_MAJOR) + && (minor >= VM_WITH_MULTIDEX_VERSION_MINOR)); + } catch (NumberFormatException ignore) { + // let isMultidexCapable be false + } + } + } + } + } catch (Exception ignore) { + + } + + Log.i(TAG, "VM with name " + vmName + (isMultidexCapable ? " has multidex support" : " does not have multidex support")); + return isMultidexCapable; + } + + /** + * 判断系统是否为YunOS系统 + */ + private static boolean isYunOS() { + try { + String version = System.getProperty("ro.yunos.version"); + String vmName = System.getProperty("java.vm.name"); + return (vmName != null && vmName.toLowerCase().contains("lemur")) + || (version != null && version.trim().length() > 0); + } catch (Exception ignore) { + return false; + } + } +} \ No newline at end of file diff --git a/lib_common/src/main/java/com/guiying/module/common/base/IApplicationDelegate.java b/lib_common/src/main/java/com/guiying/module/common/base/IApplicationDelegate.java new file mode 100644 index 0000000..1ea31b6 --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/base/IApplicationDelegate.java @@ -0,0 +1,23 @@ +package com.guiying.module.common.base; + +import android.support.annotation.Keep; + +/** + *

类说明

+ * + * @author 张华洋 2017/9/20 22:23 + * @version V2.8.3 + * @name ApplicationDelegate + */ +@Keep +public interface IApplicationDelegate { + + void onCreate(); + + void onTerminate(); + + void onLowMemory(); + + void onTrimMemory(int level); + +} diff --git a/lib_common/src/main/java/com/guiying/module/common/base/IViewDelegate.java b/lib_common/src/main/java/com/guiying/module/common/base/IViewDelegate.java new file mode 100644 index 0000000..3c35b8e --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/base/IViewDelegate.java @@ -0,0 +1,21 @@ +package com.guiying.module.common.base; + + +import android.support.annotation.Keep; +import android.view.View; + +/** + *

类说明

+ * + * @author 张华洋 2018/1/4 22:10 + * @version V2.8.3 + * @name IFragmentDelegate + */ +@Keep +public interface IViewDelegate { + + BaseFragment getFragment(String name); + + View getView(String name); + +} diff --git a/lib_common/src/main/java/com/guiying/common/base/InfoCallback.java b/lib_common/src/main/java/com/guiying/module/common/base/InfoCallback.java similarity index 72% rename from lib_common/src/main/java/com/guiying/common/base/InfoCallback.java rename to lib_common/src/main/java/com/guiying/module/common/base/InfoCallback.java index 0024e7a..8a5cf9b 100644 --- a/lib_common/src/main/java/com/guiying/common/base/InfoCallback.java +++ b/lib_common/src/main/java/com/guiying/module/common/base/InfoCallback.java @@ -1,4 +1,6 @@ -package com.guiying.common.base; +package com.guiying.module.common.base; + +import android.support.annotation.Keep; /** *

数据回调接口

@@ -7,6 +9,7 @@ * @version V1.2.0 * @name InfoCallback */ +@Keep public interface InfoCallback { void onSuccess(T info); diff --git a/lib_common/src/main/java/com/guiying/common/base/BaseApplication.java b/lib_common/src/main/java/com/guiying/module/common/base/ViewManager.java similarity index 58% rename from lib_common/src/main/java/com/guiying/common/base/BaseApplication.java rename to lib_common/src/main/java/com/guiying/module/common/base/ViewManager.java index 319ee04..8f221a0 100644 --- a/lib_common/src/main/java/com/guiying/common/base/BaseApplication.java +++ b/lib_common/src/main/java/com/guiying/module/common/base/ViewManager.java @@ -1,64 +1,82 @@ -package com.guiying.common.base; +package com.guiying.module.common.base; import android.app.Activity; -import android.app.ActivityManager; -import android.app.Application; import android.content.Context; +import android.support.annotation.Keep; import android.util.Log; -import com.guiying.common.utils.Utils; -import com.orhanobut.logger.LogLevel; -import com.orhanobut.logger.Logger; - +import java.util.ArrayList; +import java.util.List; import java.util.Stack; /** - * 要想使用BaseApplication,必须在组件中实现自己的Application,并且继承BaseApplication; - * 组件中实现的Application必须在debug包中的AndroidManifest.xml中注册,否则无法使用; - * 组件的Application需置于java/debug文件夹中,不得放于主代码; - * 组件中获取Context的方法必须为:Utils.getContext(),不允许其他写法; - * BaseApplication主要用来管理全局Activity; + *

* - * @author 2016/12/2 17:02 - * @version V1.0.0 - * @name BaseApplication + * @author 张华洋 2017/9/26 22:26 + * @version V1.1 + * @name ViewManager */ -public class BaseApplication extends Application { +@Keep +public class ViewManager { + + private static Stack activityStack; + private static List fragmentList; + + public static ViewManager getInstance() { + return ViewManagerHolder.sInstance; + } - private static BaseApplication sInstance; + private static class ViewManagerHolder { + private static final ViewManager sInstance = new ViewManager(); + } - private Stack activityStack; + private ViewManager() { + } - public static BaseApplication getIns() { - return sInstance; + public void addFragment(int index, BaseFragment fragment) { + if (fragmentList == null) { + fragmentList = new ArrayList<>(); + } + fragmentList.add(index, fragment); + } + + + public BaseFragment getFragment(int index) { + if (fragmentList != null) { + return fragmentList.get(index); + } + return null; } - @Override - public void onCreate() { - super.onCreate(); - sInstance = this; - Utils.init(this); - Logger.init("pattern").logLevel(LogLevel.FULL); + public List getAllFragment() { + if (fragmentList != null) { + return fragmentList; + } + return null; } + /** * 添加指定Activity到堆栈 */ public void addActivity(Activity activity) { if (activityStack == null) { - activityStack = new Stack<>(); + activityStack = new Stack(); } activityStack.add(activity); } + /** * 获取当前Activity */ public Activity currentActivity() { - return activityStack.lastElement(); + Activity activity = activityStack.lastElement(); + return activity; } + /** * 结束当前Activity */ @@ -67,6 +85,7 @@ public void finishActivity() { finishActivity(activity); } + /** * 结束指定的Activity */ @@ -78,6 +97,7 @@ public void finishActivity(Activity activity) { } } + /** * 结束指定Class的Activity */ @@ -90,6 +110,7 @@ public void finishActivity(Class cls) { } } + /** * 结束全部的Activity */ @@ -102,6 +123,7 @@ public void finishAllActivity() { activityStack.clear(); } + /** * 退出应用程序 */ @@ -109,13 +131,11 @@ public void exitApp(Context context) { try { finishAllActivity(); //杀死后台进程需要在AndroidManifest中声明android.permission.KILL_BACKGROUND_PROCESSES; - ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + android.app.ActivityManager activityManager = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); activityManager.killBackgroundProcesses(context.getPackageName()); //System.exit(0); } catch (Exception e) { Log.e("ActivityManager", "app exit" + e.getMessage()); } } - - } diff --git a/lib_common/src/main/java/com/guiying/module/common/glide/ImageUtils.java b/lib_common/src/main/java/com/guiying/module/common/glide/ImageUtils.java new file mode 100644 index 0000000..6bd37ee --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/glide/ImageUtils.java @@ -0,0 +1,133 @@ +package com.guiying.module.common.glide; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.request.animation.GlideAnimation; +import com.bumptech.glide.request.target.GlideDrawableImageViewTarget; +import com.bumptech.glide.request.target.SimpleTarget; +import com.guiying.module.common.utils.Utils; + +/** + *

图片加载工具类

+ * + * @name ImageUtils + */ +public class ImageUtils { + + /** + * 默认加载 + */ + public static void loadImageView(String path, ImageView mImageView) { + Glide.with(mImageView.getContext()).load(path).into(mImageView); + } + + public static void loadImageWithError(String path, int errorRes, ImageView mImageView) { + Glide.with(mImageView.getContext()) + .load(path) + .crossFade() + .diskCacheStrategy(DiskCacheStrategy.SOURCE) + .error(errorRes) + .into(mImageView); + } + + /** + * 设置加载中以及加载失败图片 + */ + public static void loadImageWithLoading(String path, ImageView mImageView, int lodingImage, int errorRes) { + Glide.with(mImageView.getContext()).load(path).placeholder(lodingImage). + error(errorRes).into(mImageView); + } + + /** + * 设置加载动画 + * api也提供了几个常用的动画:比如crossFade() + */ + public static void loadImageViewAnim(String path, int anim, ImageView mImageView) { + Glide.with(mImageView.getContext()).load(path).animate(anim).into(mImageView); + } + + + /** + * 加载为bitmap + * + * @param path 图片地址 + * @param listener 回调 + */ + public static void loadBitMap(String path, final onLoadBitmap listener) { + Glide.with(Utils.getContext()).load(path).asBitmap().into(new SimpleTarget() { + + @Override + public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) { + listener.onReady(bitmap); + } + + @Override + public void onLoadFailed(Exception e, Drawable errorDrawable) { + listener.onFailed(); + } + }); + } + + /** + * 显示加载进度 + * + * @param path 图片地址 + * @param mImageView 图片控件 + * @param loadView 加载view + */ + public static void loadImageWithProgress(String path, final ImageView mImageView, final View loadView, int errorRes) { + Glide.with(mImageView.getContext()).load(path).error(errorRes).into(new GlideDrawableImageViewTarget(mImageView) { + @Override + public void onResourceReady(GlideDrawable resource, GlideAnimation animation) { + super.onResourceReady(resource, animation); + loadView.setVisibility(View.GONE); + } + + @Override + public void onLoadFailed(Exception e, Drawable errorDrawable) { + super.onLoadFailed(e, errorDrawable); + loadView.setVisibility(View.GONE); + } + }); + } + + /** + * 清除view上的图片 + * + * @param view 视图 + */ + public static void clearImageView(View view) { + Glide.clear(view); + } + + /** + * 清理磁盘缓存需要在子线程中执行 + */ + public static void GuideClearDiskCache(Context mContext) { + Glide.get(mContext).clearDiskCache(); + } + + /** + * 清理内存缓存可以在UI主线程中进行 + */ + public static void GuideClearMemory(Context mContext) { + Glide.get(mContext).clearMemory(); + } + + /** + * 加载bitmap回调 + */ + public interface onLoadBitmap { + void onReady(Bitmap resource); + + void onFailed(); + } + +} \ No newline at end of file diff --git a/lib_common/src/main/java/com/guiying/common/glide/OkHttpGlideModule.java b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpGlideModule.java similarity index 98% rename from lib_common/src/main/java/com/guiying/common/glide/OkHttpGlideModule.java rename to lib_common/src/main/java/com/guiying/module/common/glide/OkHttpGlideModule.java index ba8969a..1fedd2e 100644 --- a/lib_common/src/main/java/com/guiying/common/glide/OkHttpGlideModule.java +++ b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpGlideModule.java @@ -1,4 +1,4 @@ -package com.guiying.common.glide; +package com.guiying.module.common.glide; import android.content.Context; diff --git a/lib_common/src/main/java/com/guiying/common/glide/OkHttpStreamFetcher.java b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpStreamFetcher.java similarity index 95% rename from lib_common/src/main/java/com/guiying/common/glide/OkHttpStreamFetcher.java rename to lib_common/src/main/java/com/guiying/module/common/glide/OkHttpStreamFetcher.java index 358afd3..efd1560 100644 --- a/lib_common/src/main/java/com/guiying/common/glide/OkHttpStreamFetcher.java +++ b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpStreamFetcher.java @@ -1,10 +1,10 @@ -package com.guiying.common.glide; +package com.guiying.module.common.glide; import com.bumptech.glide.Priority; import com.bumptech.glide.load.data.DataFetcher; import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.util.ContentLengthInputStream; -import com.guiying.common.utils.CloseUtils; +import com.guiying.module.common.utils.CloseUtils; import java.io.IOException; import java.io.InputStream; diff --git a/lib_common/src/main/java/com/guiying/common/glide/OkHttpUrlLoader.java b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpUrlLoader.java similarity index 98% rename from lib_common/src/main/java/com/guiying/common/glide/OkHttpUrlLoader.java rename to lib_common/src/main/java/com/guiying/module/common/glide/OkHttpUrlLoader.java index 89f166d..c456435 100644 --- a/lib_common/src/main/java/com/guiying/common/glide/OkHttpUrlLoader.java +++ b/lib_common/src/main/java/com/guiying/module/common/glide/OkHttpUrlLoader.java @@ -1,4 +1,4 @@ -package com.guiying.common.glide; +package com.guiying.module.common.glide; import android.content.Context; diff --git a/lib_common/src/main/java/com/guiying/common/http/ApiService.java b/lib_common/src/main/java/com/guiying/module/common/http/ApiService.java similarity index 97% rename from lib_common/src/main/java/com/guiying/common/http/ApiService.java rename to lib_common/src/main/java/com/guiying/module/common/http/ApiService.java index fa73d0a..895b72e 100644 --- a/lib_common/src/main/java/com/guiying/common/http/ApiService.java +++ b/lib_common/src/main/java/com/guiying/module/common/http/ApiService.java @@ -1,4 +1,4 @@ -package com.guiying.common.http; +package com.guiying.module.common.http; import java.util.Map; diff --git a/lib_common/src/main/java/com/guiying/common/http/DataParseUtil.java b/lib_common/src/main/java/com/guiying/module/common/http/DataParseUtil.java similarity index 98% rename from lib_common/src/main/java/com/guiying/common/http/DataParseUtil.java rename to lib_common/src/main/java/com/guiying/module/common/http/DataParseUtil.java index dafb631..9cbc61b 100644 --- a/lib_common/src/main/java/com/guiying/common/http/DataParseUtil.java +++ b/lib_common/src/main/java/com/guiying/module/common/http/DataParseUtil.java @@ -1,4 +1,4 @@ -package com.guiying.common.http; +package com.guiying.module.common.http; import android.text.TextUtils; diff --git a/lib_common/src/main/java/com/guiying/common/http/DataType.java b/lib_common/src/main/java/com/guiying/module/common/http/DataType.java similarity index 95% rename from lib_common/src/main/java/com/guiying/common/http/DataType.java rename to lib_common/src/main/java/com/guiying/module/common/http/DataType.java index 906fde6..7847996 100644 --- a/lib_common/src/main/java/com/guiying/common/http/DataType.java +++ b/lib_common/src/main/java/com/guiying/module/common/http/DataType.java @@ -1,4 +1,4 @@ -package com.guiying.common.http; +package com.guiying.module.common.http; import android.support.annotation.IntDef; diff --git a/lib_common/src/main/java/com/guiying/common/http/HttpClient.java b/lib_common/src/main/java/com/guiying/module/common/http/HttpClient.java similarity index 96% rename from lib_common/src/main/java/com/guiying/common/http/HttpClient.java rename to lib_common/src/main/java/com/guiying/module/common/http/HttpClient.java index 8ebbd04..2be900b 100644 --- a/lib_common/src/main/java/com/guiying/common/http/HttpClient.java +++ b/lib_common/src/main/java/com/guiying/module/common/http/HttpClient.java @@ -1,4 +1,4 @@ -package com.guiying.common.http; +package com.guiying.module.common.http; import android.support.annotation.NonNull; import android.text.TextUtils; @@ -7,11 +7,11 @@ import com.franmontiel.persistentcookiejar.PersistentCookieJar; import com.franmontiel.persistentcookiejar.cache.SetCookieCache; import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor; -import com.guiying.common.R; -import com.guiying.common.utils.NetworkUtils; -import com.guiying.common.utils.StringUtils; -import com.guiying.common.utils.ToastUtils; -import com.guiying.common.utils.Utils; +import com.guiying.module.common.R; +import com.guiying.module.common.utils.NetworkUtils; +import com.guiying.module.common.utils.StringUtils; +import com.guiying.module.common.utils.ToastUtils; +import com.guiying.module.common.utils.Utils; import com.orhanobut.logger.Logger; import java.io.IOException; @@ -141,7 +141,7 @@ public void onResponse(Call call, Response response) try { String result = response.body().string(); parseData(result, builder.clazz, builder.bodyType, onResultListener); - } catch (IOException e) { + } catch (IOException | IllegalStateException e) { e.printStackTrace(); } } diff --git a/lib_common/src/main/java/com/guiying/common/http/HttpsUtils.java b/lib_common/src/main/java/com/guiying/module/common/http/HttpsUtils.java similarity index 99% rename from lib_common/src/main/java/com/guiying/common/http/HttpsUtils.java rename to lib_common/src/main/java/com/guiying/module/common/http/HttpsUtils.java index 9245b8b..314d6ce 100644 --- a/lib_common/src/main/java/com/guiying/common/http/HttpsUtils.java +++ b/lib_common/src/main/java/com/guiying/module/common/http/HttpsUtils.java @@ -1,10 +1,10 @@ -package com.guiying.common.http; +package com.guiying.module.common.http; import android.content.Context; import android.support.annotation.RawRes; import android.text.TextUtils; -import com.guiying.common.utils.CloseUtils; +import com.guiying.module.common.utils.CloseUtils; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/lib_common/src/main/java/com/guiying/common/http/LoggerInterceptor.java b/lib_common/src/main/java/com/guiying/module/common/http/LoggerInterceptor.java similarity index 99% rename from lib_common/src/main/java/com/guiying/common/http/LoggerInterceptor.java rename to lib_common/src/main/java/com/guiying/module/common/http/LoggerInterceptor.java index 46cbff8..16d0660 100644 --- a/lib_common/src/main/java/com/guiying/common/http/LoggerInterceptor.java +++ b/lib_common/src/main/java/com/guiying/module/common/http/LoggerInterceptor.java @@ -1,4 +1,4 @@ -package com.guiying.common.http; +package com.guiying.module.common.http; import android.text.TextUtils; diff --git a/lib_common/src/main/java/com/guiying/common/http/OnResultListener.java b/lib_common/src/main/java/com/guiying/module/common/http/OnResultListener.java similarity index 94% rename from lib_common/src/main/java/com/guiying/common/http/OnResultListener.java rename to lib_common/src/main/java/com/guiying/module/common/http/OnResultListener.java index 6274b58..527f5f0 100644 --- a/lib_common/src/main/java/com/guiying/common/http/OnResultListener.java +++ b/lib_common/src/main/java/com/guiying/module/common/http/OnResultListener.java @@ -1,4 +1,4 @@ -package com.guiying.common.http; +package com.guiying.module.common.http; /** *

在Retrofit中接口会导致泛型擦除,所以这里回调使用Class

diff --git a/lib_common/src/main/java/com/guiying/common/utils/CloseUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/CloseUtils.java similarity index 96% rename from lib_common/src/main/java/com/guiying/common/utils/CloseUtils.java rename to lib_common/src/main/java/com/guiying/module/common/utils/CloseUtils.java index dae8eca..336cde0 100644 --- a/lib_common/src/main/java/com/guiying/common/utils/CloseUtils.java +++ b/lib_common/src/main/java/com/guiying/module/common/utils/CloseUtils.java @@ -1,4 +1,4 @@ -package com.guiying.common.utils; +package com.guiying.module.common.utils; import java.io.Closeable; import java.io.IOException; diff --git a/lib_common/src/main/java/com/guiying/common/utils/NetworkUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/NetworkUtils.java similarity index 99% rename from lib_common/src/main/java/com/guiying/common/utils/NetworkUtils.java rename to lib_common/src/main/java/com/guiying/module/common/utils/NetworkUtils.java index 06c8800..e788077 100644 --- a/lib_common/src/main/java/com/guiying/common/utils/NetworkUtils.java +++ b/lib_common/src/main/java/com/guiying/module/common/utils/NetworkUtils.java @@ -1,4 +1,4 @@ -package com.guiying.common.utils; +package com.guiying.module.common.utils; import android.content.Context; import android.content.Intent; diff --git a/lib_common/src/main/java/com/guiying/module/common/utils/ScreenLockUtil.java b/lib_common/src/main/java/com/guiying/module/common/utils/ScreenLockUtil.java new file mode 100644 index 0000000..d85c106 --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/utils/ScreenLockUtil.java @@ -0,0 +1,84 @@ +package com.guiying.module.common.utils; + +import android.app.Activity; +import android.app.KeyguardManager; +import android.app.KeyguardManager.KeyguardLock; +import android.content.Context; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.util.Log; + +import java.util.HashMap; + +/** + * 用于保持屏幕高亮的工具 + */ +public class ScreenLockUtil { + private static final String TAG = "ScreenLockUtil"; + + private ScreenLockUtil() { + throw new UnsupportedOperationException("cannot be instantiated"); + } + + static private HashMap mWakeLockArray = new HashMap<>(); + static private HashMap mIsUnlockArray = new HashMap<>(); + + + /** + * 保持屏幕常亮 + * + * @param activity you know + */ + public static void keepScreenOn(Activity activity) { + WakeLock wakeLock = mWakeLockArray.get(activity); + if (wakeLock == null) { + PowerManager powerManager = (PowerManager) activity.getSystemService(Context.POWER_SERVICE); + wakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.FULL_WAKE_LOCK, + activity.getClass().getName()); + } + + if (!wakeLock.isHeld()) { + wakeLock.acquire(); + } + + mWakeLockArray.put(activity, wakeLock); + + cancelLockScreen(activity); + + Log.i(TAG, "开启屏幕常亮"); + } + + + /** + * 取消屏幕常亮 + * + * @param activity you know + */ + public static void cancelKeepScreen(Activity activity) { + WakeLock wakeLock = mWakeLockArray.get(activity); + if (wakeLock != null) { + if (wakeLock.isHeld()) { + wakeLock.release(); + } + } + + Log.i(TAG, "取消屏幕常亮"); + } + + /** + * 取消锁屏限制 + * + * @param activity you know + */ + private static void cancelLockScreen(Activity activity) { + Boolean isUnlock = mIsUnlockArray.get(activity); + if (isUnlock != null && isUnlock) { + return; + } + KeyguardManager mKeyguardManager = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE); + KeyguardLock mKeyguardLock = mKeyguardManager.newKeyguardLock(activity.getClass().getName()); + mKeyguardLock.disableKeyguard(); + + mIsUnlockArray.put(activity, true); + } +} diff --git a/lib_common/src/main/java/com/guiying/common/utils/ShellUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/ShellUtils.java similarity index 99% rename from lib_common/src/main/java/com/guiying/common/utils/ShellUtils.java rename to lib_common/src/main/java/com/guiying/module/common/utils/ShellUtils.java index 138f7d5..ff326cc 100644 --- a/lib_common/src/main/java/com/guiying/common/utils/ShellUtils.java +++ b/lib_common/src/main/java/com/guiying/module/common/utils/ShellUtils.java @@ -1,4 +1,4 @@ -package com.guiying.common.utils; +package com.guiying.module.common.utils; import java.io.BufferedReader; import java.io.DataOutputStream; diff --git a/lib_common/src/main/java/com/guiying/common/utils/StringUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/StringUtils.java similarity index 99% rename from lib_common/src/main/java/com/guiying/common/utils/StringUtils.java rename to lib_common/src/main/java/com/guiying/module/common/utils/StringUtils.java index ccfbd93..e09c3ae 100644 --- a/lib_common/src/main/java/com/guiying/common/utils/StringUtils.java +++ b/lib_common/src/main/java/com/guiying/module/common/utils/StringUtils.java @@ -1,4 +1,4 @@ -package com.guiying.common.utils; +package com.guiying.module.common.utils; /** * 字符串相关工具类 diff --git a/lib_common/src/main/java/com/guiying/common/utils/ToastUtils.java b/lib_common/src/main/java/com/guiying/module/common/utils/ToastUtils.java similarity index 99% rename from lib_common/src/main/java/com/guiying/common/utils/ToastUtils.java rename to lib_common/src/main/java/com/guiying/module/common/utils/ToastUtils.java index 5b0fe84..1fd0cdb 100644 --- a/lib_common/src/main/java/com/guiying/common/utils/ToastUtils.java +++ b/lib_common/src/main/java/com/guiying/module/common/utils/ToastUtils.java @@ -1,4 +1,4 @@ -package com.guiying.common.utils; +package com.guiying.module.common.utils; import android.os.Handler; import android.os.Looper; diff --git a/lib_common/src/main/java/com/guiying/common/utils/Utils.java b/lib_common/src/main/java/com/guiying/module/common/utils/Utils.java similarity index 71% rename from lib_common/src/main/java/com/guiying/common/utils/Utils.java rename to lib_common/src/main/java/com/guiying/module/common/utils/Utils.java index 6c8b104..a06d64d 100644 --- a/lib_common/src/main/java/com/guiying/common/utils/Utils.java +++ b/lib_common/src/main/java/com/guiying/module/common/utils/Utils.java @@ -1,4 +1,5 @@ -package com.guiying.common.utils; +package com.guiying.module.common.utils; + import android.app.Activity; import android.content.Context; @@ -7,6 +8,9 @@ import android.content.pm.PackageManager; import android.support.annotation.NonNull; import android.support.annotation.StringRes; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; import android.view.View; /** @@ -87,4 +91,26 @@ public static boolean isAppDebug() { } } + + /** + * The {@code fragment} is added to the container view with id {@code frameId}. The operation is + * performed by the {@code fragmentManager}. + */ + public static void addFragmentToActivity(@NonNull FragmentManager fragmentManager, + @NonNull Fragment fragment, int frameId) { + checkNotNull(fragmentManager); + checkNotNull(fragment); + FragmentTransaction transaction = fragmentManager.beginTransaction(); + transaction.add(frameId, fragment); + transaction.commit(); + } + + + public static T checkNotNull(T obj) { + if (obj == null) { + throw new NullPointerException(); + } + return obj; + } + } \ No newline at end of file diff --git a/lib_common/src/main/java/com/guiying/common/HackyViewPager.java b/lib_common/src/main/java/com/guiying/module/common/widget/HackyViewPager.java similarity index 80% rename from lib_common/src/main/java/com/guiying/common/HackyViewPager.java rename to lib_common/src/main/java/com/guiying/module/common/widget/HackyViewPager.java index f3a1692..a9ace60 100644 --- a/lib_common/src/main/java/com/guiying/common/HackyViewPager.java +++ b/lib_common/src/main/java/com/guiying/module/common/widget/HackyViewPager.java @@ -1,4 +1,4 @@ -package com.guiying.common; +package com.guiying.module.common.widget; import android.content.Context; import android.support.v4.view.ViewPager; @@ -6,7 +6,10 @@ import android.view.MotionEvent; /** - *

解决图片缩放崩溃的问题

+ *

解决图片缩放崩溃的问题

+ * @name HackyViewPager + * @author 张华洋 2017/9/27 10:10 + * @version V1.1 */ public class HackyViewPager extends ViewPager { diff --git a/lib_common/src/main/java/com/guiying/module/common/widget/NoScrollViewPager.java b/lib_common/src/main/java/com/guiying/module/common/widget/NoScrollViewPager.java new file mode 100644 index 0000000..be8f2b9 --- /dev/null +++ b/lib_common/src/main/java/com/guiying/module/common/widget/NoScrollViewPager.java @@ -0,0 +1,41 @@ +package com.guiying.module.common.widget; + +import android.content.Context; +import android.support.v4.view.ViewPager; +import android.util.AttributeSet; +import android.view.MotionEvent; + +/** + *

可以禁止滑动翻页的ViewPager

+ * + * @author 张华洋 2017/9/27 10:10 + * @version V1.1 + * @name NoScrollViewPager + */ +public class NoScrollViewPager extends ViewPager { + + private boolean isPagingEnabled = true; + + public NoScrollViewPager(Context context) { + super(context); + } + + public NoScrollViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + return this.isPagingEnabled && super.onTouchEvent(event); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + return this.isPagingEnabled && super.onInterceptTouchEvent(event); + } + + public void setPagerEnabled(boolean b) { + this.isPagingEnabled = b; + } + +} diff --git a/module_app/build.gradle b/module_app/build.gradle index 37c526b..2776c5c 100644 --- a/module_app/build.gradle +++ b/module_app/build.gradle @@ -1,5 +1,13 @@ apply plugin: 'com.android.application' +// Create a variable called keystorePropertiesFile, and initialize it to your +// keystore.properties file, in the rootProject folder. +def keystorePropertiesFile = rootProject.file("keystore.properties") +// Initialize a new Properties() object called keystoreProperties. +def keystoreProperties = new Properties() +// Load your keystore.properties file into the keystoreProperties object. +keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) + static def buildTime() { return new Date().format("yyyyMMdd"); } @@ -7,26 +15,31 @@ static def buildTime() { android { signingConfigs { release { - keyAlias 'guiying712' - keyPassword 'guiying712' - storeFile file('/mykey.jks') - storePassword 'guiying712' + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile file(keystoreProperties['storeFile']) + storePassword keystoreProperties['storePassword'] } } - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion + compileSdkVersion build_versions.target_sdk defaultConfig { - applicationId "com.guiying.androidmodulepattern" - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode rootProject.ext.versionCode - versionName rootProject.ext.versionName + applicationId "com.guiying.module" + minSdkVersion build_versions.min_sdk + targetSdkVersion build_versions.target_sdk + versionCode 1 + versionName "1.0" multiDexEnabled true //打包时间 resValue "string", "build_time", buildTime() } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + buildTypes { release { //更改AndroidManifest.xml中预先定义好占位符信息 @@ -60,13 +73,12 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:multidex:1.0.1' - if (isModule.toBoolean()) { - compile project(':lib_common') - } else { - compile project(':module_main') - compile project(':module_girls') - compile project(':module_news') + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation deps.support.multidex + implementation project(':lib_common') + if (!isModule.toBoolean()) { + implementation project(':module_main') + implementation project(':module_girls') + implementation project(':module_news') } } diff --git a/module_app/src/main/AndroidManifest.xml b/module_app/src/main/AndroidManifest.xml index 725abcf..315d6cb 100644 --- a/module_app/src/main/AndroidManifest.xml +++ b/module_app/src/main/AndroidManifest.xml @@ -1,9 +1,9 @@ + package="com.guiying.module"> + package="com.guiying.module.girls"> 类说明

+ * + * @author 张华洋 2017/9/20 22:29 + * @version V2.8.3 + * @name MyDelegate + */ +@Keep +public class MyDelegate implements IApplicationDelegate { + + @Override + public void onCreate() { + //主动添加 + ViewManager.getInstance().addFragment(0, GirlsFragment.newInstance()); + } + + @Override + public void onTerminate() { + + } + + @Override + public void onLowMemory() { + + } + + @Override + public void onTrimMemory(int level) { + + } +} diff --git a/module_girls/src/main/java/com/guiying/module/girls/MyViewDelegate.java b/module_girls/src/main/java/com/guiying/module/girls/MyViewDelegate.java new file mode 100644 index 0000000..3d4294e --- /dev/null +++ b/module_girls/src/main/java/com/guiying/module/girls/MyViewDelegate.java @@ -0,0 +1,28 @@ +package com.guiying.module.girls; + +import android.support.annotation.Keep; +import android.view.View; + +import com.guiying.module.common.base.BaseFragment; +import com.guiying.module.common.base.IViewDelegate; + +/** + *

类说明

+ * + * @author 张华洋 2018/1/4 22:16 + * @version V2.8.3 + * @name MyViewDelegate + */ +@Keep +public class MyViewDelegate implements IViewDelegate { + + @Override + public BaseFragment getFragment(String name) { + return GirlsFragment.newInstance(); + } + + @Override + public View getView(String name) { + return null; + } +} diff --git a/module_girls/src/main/java/com/guiying/girls/data/GirlsDataSource.java b/module_girls/src/main/java/com/guiying/module/girls/data/GirlsDataSource.java similarity index 71% rename from module_girls/src/main/java/com/guiying/girls/data/GirlsDataSource.java rename to module_girls/src/main/java/com/guiying/module/girls/data/GirlsDataSource.java index 4e92618..3f2755d 100644 --- a/module_girls/src/main/java/com/guiying/girls/data/GirlsDataSource.java +++ b/module_girls/src/main/java/com/guiying/module/girls/data/GirlsDataSource.java @@ -1,6 +1,6 @@ -package com.guiying.girls.data; +package com.guiying.module.girls.data; -import com.guiying.girls.data.bean.GirlsParser; +import com.guiying.module.girls.data.bean.GirlsParser; public interface GirlsDataSource { diff --git a/module_girls/src/main/java/com/guiying/girls/data/bean/Girls.java b/module_girls/src/main/java/com/guiying/module/girls/data/bean/Girls.java similarity index 98% rename from module_girls/src/main/java/com/guiying/girls/data/bean/Girls.java rename to module_girls/src/main/java/com/guiying/module/girls/data/bean/Girls.java index 162b6b5..26573c9 100644 --- a/module_girls/src/main/java/com/guiying/girls/data/bean/Girls.java +++ b/module_girls/src/main/java/com/guiying/module/girls/data/bean/Girls.java @@ -1,4 +1,4 @@ -package com.guiying.girls.data.bean; +package com.guiying.module.girls.data.bean; import android.os.Parcel; import android.os.Parcelable; diff --git a/module_girls/src/main/java/com/guiying/girls/data/bean/GirlsParser.java b/module_girls/src/main/java/com/guiying/module/girls/data/bean/GirlsParser.java similarity index 96% rename from module_girls/src/main/java/com/guiying/girls/data/bean/GirlsParser.java rename to module_girls/src/main/java/com/guiying/module/girls/data/bean/GirlsParser.java index b18db5c..d9c4d34 100644 --- a/module_girls/src/main/java/com/guiying/girls/data/bean/GirlsParser.java +++ b/module_girls/src/main/java/com/guiying/module/girls/data/bean/GirlsParser.java @@ -1,4 +1,4 @@ -package com.guiying.girls.data.bean; +package com.guiying.module.girls.data.bean; import java.util.List; diff --git a/module_girls/src/main/java/com/guiying/girls/data/source/RemoteGirlsDataSource.java b/module_girls/src/main/java/com/guiying/module/girls/data/source/RemoteGirlsDataSource.java similarity index 72% rename from module_girls/src/main/java/com/guiying/girls/data/source/RemoteGirlsDataSource.java rename to module_girls/src/main/java/com/guiying/module/girls/data/source/RemoteGirlsDataSource.java index ae343f3..457f412 100644 --- a/module_girls/src/main/java/com/guiying/girls/data/source/RemoteGirlsDataSource.java +++ b/module_girls/src/main/java/com/guiying/module/girls/data/source/RemoteGirlsDataSource.java @@ -1,12 +1,12 @@ -package com.guiying.girls.data.source; +package com.guiying.module.girls.data.source; -import com.guiying.common.http.DataType; -import com.guiying.common.http.HttpClient; -import com.guiying.common.http.OnResultListener; -import com.guiying.girls.Constants; -import com.guiying.girls.data.GirlsDataSource; -import com.guiying.girls.data.bean.GirlsParser; +import com.guiying.module.common.http.DataType; +import com.guiying.module.common.http.HttpClient; +import com.guiying.module.common.http.OnResultListener; +import com.guiying.module.girls.Constants; +import com.guiying.module.girls.data.GirlsDataSource; +import com.guiying.module.girls.data.bean.GirlsParser; diff --git a/module_girls/src/main/java/com/guiying/girls/girl/GirlActivity.java b/module_girls/src/main/java/com/guiying/module/girls/girl/GirlActivity.java similarity index 87% rename from module_girls/src/main/java/com/guiying/girls/girl/GirlActivity.java rename to module_girls/src/main/java/com/guiying/module/girls/girl/GirlActivity.java index 9551bb6..bd1dd78 100644 --- a/module_girls/src/main/java/com/guiying/girls/girl/GirlActivity.java +++ b/module_girls/src/main/java/com/guiying/module/girls/girl/GirlActivity.java @@ -1,14 +1,14 @@ -package com.guiying.girls.girl; +package com.guiying.module.girls.girl; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.view.WindowManager; import com.alibaba.android.arouter.facade.annotation.Route; -import com.guiying.common.HackyViewPager; -import com.guiying.common.base.BaseActivity; -import com.guiying.girls.Constants; -import com.guiying.girls.data.bean.Girls; +import com.guiying.module.common.base.BaseActivity; +import com.guiying.module.common.widget.HackyViewPager; +import com.guiying.module.girls.Constants; +import com.guiying.module.girls.data.bean.Girls; import java.util.List; diff --git a/module_girls/src/main/java/com/guiying/girls/girl/GirlAdapter.java b/module_girls/src/main/java/com/guiying/module/girls/girl/GirlAdapter.java similarity index 93% rename from module_girls/src/main/java/com/guiying/girls/girl/GirlAdapter.java rename to module_girls/src/main/java/com/guiying/module/girls/girl/GirlAdapter.java index 6c2bb1d..dce7361 100644 --- a/module_girls/src/main/java/com/guiying/girls/girl/GirlAdapter.java +++ b/module_girls/src/main/java/com/guiying/module/girls/girl/GirlAdapter.java @@ -1,4 +1,4 @@ -package com.guiying.girls.girl; +package com.guiying.module.girls.girl; import android.content.Context; import android.support.v4.view.PagerAdapter; @@ -8,8 +8,8 @@ import com.bumptech.glide.Glide; import com.github.chrisbanes.photoview.PhotoView; -import com.guiying.girls.R; -import com.guiying.girls.data.bean.Girls; +import com.guiying.module.girls.R; +import com.guiying.module.girls.data.bean.Girls; import java.util.List; diff --git a/module_girls/src/main/java/com/guiying/girls/main/GirlsActivity.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsActivity.java similarity index 82% rename from module_girls/src/main/java/com/guiying/girls/main/GirlsActivity.java rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsActivity.java index 9ebdf52..9a64571 100644 --- a/module_girls/src/main/java/com/guiying/girls/main/GirlsActivity.java +++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsActivity.java @@ -1,10 +1,10 @@ -package com.guiying.girls.main; +package com.guiying.module.girls.main; import android.os.Bundle; import com.alibaba.android.arouter.facade.annotation.Route; -import com.guiying.common.base.BaseActionBarActivity; -import com.guiying.girls.R; +import com.guiying.module.common.base.BaseActionBarActivity; +import com.guiying.module.girls.R; @Route(path = "/girls/list") public class GirlsActivity extends BaseActionBarActivity { diff --git a/module_girls/src/main/java/com/guiying/girls/main/GirlsAdapter.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsAdapter.java similarity index 93% rename from module_girls/src/main/java/com/guiying/girls/main/GirlsAdapter.java rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsAdapter.java index eefbad0..6ee991a 100644 --- a/module_girls/src/main/java/com/guiying/girls/main/GirlsAdapter.java +++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsAdapter.java @@ -1,4 +1,4 @@ -package com.guiying.girls.main; +package com.guiying.module.girls.main; import android.content.Context; import android.view.View; @@ -7,8 +7,8 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; -import com.guiying.girls.R; -import com.guiying.girls.data.bean.Girls; +import com.guiying.module.girls.R; +import com.guiying.module.girls.data.bean.Girls; import com.jude.easyrecyclerview.adapter.BaseViewHolder; import com.jude.easyrecyclerview.adapter.RecyclerArrayAdapter; diff --git a/module_girls/src/main/java/com/guiying/girls/main/GirlsContract.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsContract.java similarity index 76% rename from module_girls/src/main/java/com/guiying/girls/main/GirlsContract.java rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsContract.java index d4cd0d5..fd57180 100644 --- a/module_girls/src/main/java/com/guiying/girls/main/GirlsContract.java +++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsContract.java @@ -1,8 +1,8 @@ -package com.guiying.girls.main; +package com.guiying.module.girls.main; -import com.guiying.common.base.BasePresenter; -import com.guiying.common.base.BaseView; -import com.guiying.girls.data.bean.Girls; +import com.guiying.module.common.base.BasePresenter; +import com.guiying.module.common.base.BaseView; +import com.guiying.module.girls.data.bean.Girls; import java.util.List; diff --git a/module_girls/src/main/java/com/guiying/girls/main/GirlsPresenter.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsPresenter.java similarity index 84% rename from module_girls/src/main/java/com/guiying/girls/main/GirlsPresenter.java rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsPresenter.java index 8a3bca0..a94fa8b 100644 --- a/module_girls/src/main/java/com/guiying/girls/main/GirlsPresenter.java +++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsPresenter.java @@ -1,8 +1,8 @@ -package com.guiying.girls.main; +package com.guiying.module.girls.main; -import com.guiying.girls.data.GirlsDataSource; -import com.guiying.girls.data.bean.GirlsParser; -import com.guiying.girls.data.source.RemoteGirlsDataSource; +import com.guiying.module.girls.data.GirlsDataSource; +import com.guiying.module.girls.data.bean.GirlsParser; +import com.guiying.module.girls.data.source.RemoteGirlsDataSource; /** *

类说明

diff --git a/module_girls/src/main/java/com/guiying/girls/main/GirlsView.java b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsView.java similarity index 94% rename from module_girls/src/main/java/com/guiying/girls/main/GirlsView.java rename to module_girls/src/main/java/com/guiying/module/girls/main/GirlsView.java index 1c23e23..dc83d90 100644 --- a/module_girls/src/main/java/com/guiying/girls/main/GirlsView.java +++ b/module_girls/src/main/java/com/guiying/module/girls/main/GirlsView.java @@ -1,4 +1,4 @@ -package com.guiying.girls.main; +package com.guiying.module.girls.main; import android.content.Context; import android.content.Intent; @@ -11,11 +11,11 @@ import android.view.ViewStub; import android.widget.FrameLayout; -import com.guiying.common.utils.Utils; -import com.guiying.girls.Constants; -import com.guiying.girls.R; -import com.guiying.girls.data.bean.Girls; -import com.guiying.girls.girl.GirlActivity; +import com.guiying.module.common.utils.Utils; +import com.guiying.module.girls.Constants; +import com.guiying.module.girls.R; +import com.guiying.module.girls.data.bean.Girls; +import com.guiying.module.girls.girl.GirlActivity; import com.jude.easyrecyclerview.EasyRecyclerView; import com.jude.easyrecyclerview.adapter.BaseViewHolder; import com.jude.easyrecyclerview.adapter.RecyclerArrayAdapter; diff --git a/module_girls/src/main/java/debug/GirlsApplication.java b/module_girls/src/main/java/debug/GirlsApplication.java index b93eb55..052a4e6 100644 --- a/module_girls/src/main/java/debug/GirlsApplication.java +++ b/module_girls/src/main/java/debug/GirlsApplication.java @@ -1,8 +1,8 @@ package debug; -import com.guiying.common.base.BaseApplication; -import com.guiying.common.http.HttpClient; -import com.guiying.common.http.OnResultListener; +import com.guiying.module.common.base.BaseApplication; +import com.guiying.module.common.http.HttpClient; +import com.guiying.module.common.http.OnResultListener; import com.orhanobut.logger.Logger; /** diff --git a/module_girls/src/main/module/AndroidManifest.xml b/module_girls/src/main/module/AndroidManifest.xml index 4ae8556..f283bb9 100644 --- a/module_girls/src/main/module/AndroidManifest.xml +++ b/module_girls/src/main/module/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com.guiying.module.girls"> + tools:context=".girls.main.GirlsActivity"> + + + + + diff --git a/module_main/build.gradle b/module_main/build.gradle index f41c59f..a1838bd 100644 --- a/module_main/build.gradle +++ b/module_main/build.gradle @@ -5,23 +5,24 @@ if (isModule.toBoolean()) { } android { - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - + compileSdkVersion build_versions.target_sdk defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode rootProject.ext.versionCode - versionName rootProject.ext.versionName + minSdkVersion build_versions.min_sdk + targetSdkVersion build_versions.target_sdk + versionCode 1 + versionName "1.0" - //ARouter javaCompileOptions { annotationProcessorOptions { - arguments = [moduleName: project.getName()] + arguments = [ moduleName : project.getName() ] } } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } sourceSets { main { @@ -37,10 +38,16 @@ android { } } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - annotationProcessor "com.alibaba:arouter-compiler:$rootProject.annotationProcessor" - compile project(':lib_common') + implementation fileTree(dir: 'libs', include: ['*.jar']) + annotationProcessor deps.arouter_compiler + implementation project(':lib_common') } diff --git a/module_main/src/main/AndroidManifest.xml b/module_main/src/main/AndroidManifest.xml index 4249b68..db12695 100644 --- a/module_main/src/main/AndroidManifest.xml +++ b/module_main/src/main/AndroidManifest.xml @@ -1,14 +1,20 @@ + + package="com.guiying.module.main"> - + + + + - + \ No newline at end of file diff --git a/module_main/src/main/java/com/guiying/module/main/BottomNavigationActivity.java b/module_main/src/main/java/com/guiying/module/main/BottomNavigationActivity.java new file mode 100644 index 0000000..51c27cf --- /dev/null +++ b/module_main/src/main/java/com/guiying/module/main/BottomNavigationActivity.java @@ -0,0 +1,86 @@ +package com.guiying.module.main; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.design.widget.BottomNavigationView; +import android.view.MenuItem; + +import com.guiying.module.common.base.BaseActivity; +import com.guiying.module.common.base.BaseFragment; +import com.guiying.module.common.base.ClassUtils; +import com.guiying.module.common.base.IViewDelegate; +import com.guiying.module.common.base.ViewManager; +import com.guiying.module.common.widget.NoScrollViewPager; + +import java.util.List; + +/** + *

+ * + * @author 张华洋 2017/9/27 10:23 + * @version V1.1 + * @name BottomNavigationActivity + */ +public class BottomNavigationActivity extends BaseActivity { + + private NoScrollViewPager mPager; + private List mFragments; + private FragmentAdapter mAdapter; + + private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener + = new BottomNavigationView.OnNavigationItemSelectedListener() { + + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + int i = item.getItemId(); + if (i == R.id.navigation_home) { + mPager.setCurrentItem(0); + return true; + } else if (i == R.id.navigation_dashboard) { + mPager.setCurrentItem(1); + return true; + } else if (i == R.id.navigation_notifications) { + mPager.setCurrentItem(2); + return true; + } + return false; + } + + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_bottom_navigation); + BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation); + navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); + initViewPager(); + } + + private void initViewPager() { + mFragments = ViewManager.getInstance().getAllFragment();//这几个Fragment是主动添加到ViewManager中的 + BaseFragment newsFragment = getNewsFragment();//主动寻找 + mFragments.add(newsFragment); + mPager = (NoScrollViewPager) findViewById(R.id.container_pager); + mAdapter = new FragmentAdapter(getSupportFragmentManager(), mFragments); + mPager.setPagerEnabled(false); + mPager.setAdapter(mAdapter); + } + + + /** + * 在News模块中寻找实现的Fragment + * + * @return Fragment + */ + private BaseFragment getNewsFragment() { + BaseFragment newsFragment = null; + List viewDelegates = ClassUtils.getObjectsWithInterface(this, IViewDelegate.class, "com.guiying.module.news"); + if (viewDelegates != null && !viewDelegates.isEmpty()) { + newsFragment = viewDelegates.get(0).getFragment(""); + } + return newsFragment; + } + +} diff --git a/module_main/src/main/java/com/guiying/module/main/FragmentAdapter.java b/module_main/src/main/java/com/guiying/module/main/FragmentAdapter.java new file mode 100644 index 0000000..dc5b82b --- /dev/null +++ b/module_main/src/main/java/com/guiying/module/main/FragmentAdapter.java @@ -0,0 +1,40 @@ +package com.guiying.module.main; + +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; + +import com.guiying.module.common.base.BaseFragment; + +import java.util.List; + +/** + *

Fragments适配器

+ * + * @author 张华洋 2017/9/27 10:14 + * @version V1.1 + * @name ResourcePagerAdapter + */ +public class FragmentAdapter extends FragmentStatePagerAdapter { + private List mFragments; + + public FragmentAdapter(FragmentManager fm, List mFragments) { + super(fm); + this.mFragments = mFragments; + } + + @Override + public Fragment getItem(int position) { + return mFragments.get(position); + } + + @Override + public int getCount() { + return mFragments != null ? mFragments.size() : 0; + } + + @Override + public int getItemPosition(Object object) { + return android.support.v4.view.PagerAdapter.POSITION_NONE; + } +} diff --git a/module_main/src/main/java/com/guiying/main/MainActivity.java b/module_main/src/main/java/com/guiying/module/main/MainActivity.java similarity index 63% rename from module_main/src/main/java/com/guiying/main/MainActivity.java rename to module_main/src/main/java/com/guiying/module/main/MainActivity.java index dbcb530..db0fb8b 100644 --- a/module_main/src/main/java/com/guiying/main/MainActivity.java +++ b/module_main/src/main/java/com/guiying/module/main/MainActivity.java @@ -1,14 +1,14 @@ -package com.guiying.main; +package com.guiying.module.main; +import android.content.Intent; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; -import android.widget.Button; import com.alibaba.android.arouter.launcher.ARouter; -import com.guiying.common.base.BaseActivity; -import com.guiying.common.base.BaseApplication; -import com.guiying.common.utils.ToastUtils; +import com.guiying.module.common.base.BaseActivity; +import com.guiying.module.common.base.ViewManager; +import com.guiying.module.common.utils.ToastUtils; /** *

类说明

@@ -19,18 +19,15 @@ */ public class MainActivity extends BaseActivity implements View.OnClickListener { - private long exitTime = 0; - protected Button newsButton; - protected Button girlsButton; + private long mExitTime = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - newsButton = (Button) findViewById(R.id.news_button); - newsButton.setOnClickListener(MainActivity.this); - girlsButton = (Button) findViewById(R.id.girls_button); - girlsButton.setOnClickListener(MainActivity.this); + findViewById(R.id.news_button).setOnClickListener(this); + findViewById(R.id.girls_button).setOnClickListener(this); + findViewById(R.id.fragment_button).setOnClickListener(this); } @Override @@ -41,6 +38,8 @@ public void onClick(View view) { } else if (view.getId() == R.id.girls_button) { //跳转到GirlsActivity ARouter.getInstance().build("/girls/list").navigation(); + } else if (view.getId() == R.id.fragment_button) { + startActivity(new Intent(this, BottomNavigationActivity.class)); } } @@ -49,11 +48,11 @@ public void onClick(View view) { public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { //两秒之内按返回键就会退出 - if ((System.currentTimeMillis() - exitTime) > 2000) { + if ((System.currentTimeMillis() - mExitTime) > 2000) { ToastUtils.showShortToast(getString(R.string.app_exit_hint)); - exitTime = System.currentTimeMillis(); + mExitTime = System.currentTimeMillis(); } else { - BaseApplication.getIns().exitApp(this); + ViewManager.getInstance().exitApp(this); } return true; } diff --git a/module_main/src/main/java/debug/MainApplication.java b/module_main/src/main/java/debug/MainApplication.java index 293f166..24509f5 100644 --- a/module_main/src/main/java/debug/MainApplication.java +++ b/module_main/src/main/java/debug/MainApplication.java @@ -1,8 +1,8 @@ package debug; -import com.guiying.common.base.BaseApplication; -import com.guiying.common.http.HttpClient; -import com.guiying.common.http.OnResultListener; +import com.guiying.module.common.base.BaseApplication; +import com.guiying.module.common.http.HttpClient; +import com.guiying.module.common.http.OnResultListener; import com.orhanobut.logger.Logger; /** diff --git a/module_main/src/main/module/AndroidManifest.xml b/module_main/src/main/module/AndroidManifest.xml index fc3933a..0443b12 100644 --- a/module_main/src/main/module/AndroidManifest.xml +++ b/module_main/src/main/module/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com.guiying.module.main"> - + @@ -18,4 +18,4 @@ - \ No newline at end of file +
diff --git a/module_main/src/main/res/drawable/ic_dashboard_black_24dp.xml b/module_main/src/main/res/drawable/ic_dashboard_black_24dp.xml new file mode 100644 index 0000000..ae6a446 --- /dev/null +++ b/module_main/src/main/res/drawable/ic_dashboard_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/module_main/src/main/res/drawable/ic_home_black_24dp.xml b/module_main/src/main/res/drawable/ic_home_black_24dp.xml new file mode 100644 index 0000000..0c36320 --- /dev/null +++ b/module_main/src/main/res/drawable/ic_home_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/module_main/src/main/res/drawable/ic_notifications_black_24dp.xml b/module_main/src/main/res/drawable/ic_notifications_black_24dp.xml new file mode 100644 index 0000000..0262382 --- /dev/null +++ b/module_main/src/main/res/drawable/ic_notifications_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/module_main/src/main/res/layout/activity_bottom_navigation.xml b/module_main/src/main/res/layout/activity_bottom_navigation.xml new file mode 100644 index 0000000..060e7be --- /dev/null +++ b/module_main/src/main/res/layout/activity_bottom_navigation.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/module_main/src/main/res/layout/activity_main.xml b/module_main/src/main/res/layout/activity_main.xml index e5e21fe..c4c16f8 100644 --- a/module_main/src/main/res/layout/activity_main.xml +++ b/module_main/src/main/res/layout/activity_main.xml @@ -9,7 +9,7 @@ android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" - tools:context="com.guiying.main.MainActivity"> + tools:context="com.guiying.module.main.MainActivity">