defaultConfig {
if (!isNeedMeModule.toBoolean()) {
applicationId “tsou.cn.module_me”
}
}
- 在app主模块中:
if (isNeedHomeModule.toBoolean()) {
compile project(‘:module_home’)
}
if (isNeedChatModule.toBoolean()) {
compile project(‘:module_chat’)
}
if (isNeedRecomModule.toBoolean()) {
compile project(‘:module_recom’)
}
if (isNeedMeModule.toBoolean()) {
compile project(‘:module_me’)
}
如果需要单独运行某个模块时,修改gradle.properties配置,
例如单独运行module_home模块时,开启isNeedHomeModule=false,
- 方式一:直接在AndroidManifest.xml的MainActivity添加
反之则关闭!当然比较lou
- 方式二:通过build自动配置
1、主目录下AndroidManifest.xml不变
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android=“http://schemas.android.com/apk/res/android”
package=“tsou.cn.module_home”>
<application
android:allowBackup=“true”
android:icon=“@mipmap/ic_launcher”
android:label=“@string/app_name”
android:roundIcon=“@mipmap/ic_launcher_round”
android:supportsRtl=“true”
android:theme=“@style/AppTheme”>
2、在src\main目录下创建debug文件夹包含一个AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android=“http://schemas.android.com/apk/res/android”
package=“tsou.cn.module_home”>
<application
android:allowBackup=“true”
android:icon=“@mipmap/ic_launcher”
android:label=“@string/app_name”
android:roundIcon=“@mipmap/ic_launcher_round”
android:supportsRtl=“true”
android:theme=“@style/AppTheme”>
3、在子模块的build中配置
android {
…
sourceSets{
main {
if (!isNeedUseModule.toBoolean()) {
manifest.srcFile ‘src/main/debug/AndroidManifest.xml’
} else {
manifest.srcFile ‘src/main/release/AndroidManifest.xml’
java {
//全部Module一起编译的时候剔除debug目录
exclude ‘/debug/’
}
}
}
}
}
4、运行module_home即可
在lib_base中创建MyApplication
public class MyApplication extends Application {
/**
- 上下文
*/
private static MyApplication instance;
@Override
public void onCreate() {
super.onCreate();
instance = this;
initRouter(this);
}
public static Context getInstance() {
return instance;
}
private void initRouter(MyApplication mApplication) {
// 这两行必须写在init之前,否则这些配置在init过程中将无效
if (UIUtils.isApkInDebug(instance)) {
//打印日志
ARouter.openLog();
//开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!
//线上版本需要关闭,否则有安全风险)
ARouter.openDebug();
}
// 尽可能早,推荐在Application中初始化
ARouter.init(mApplication);
}
}
/**
- 判断当前应用是否是debug状态
*/
public static boolean isApkInDebug(Context context) {
try {
ApplicationInfo info = context.getApplicationInfo();
return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
} catch (Exception e) {
return false;
}
}
这里要注意:如果你在debug模式下进行调试代码,ARouter.openDebug();一定要调用,否则ARouter会出现无效情况。
使用ARouter来获取到各个模块的Fragment
package tsou.cn.lib_base.utils;
/**
- Created by Administrator on 2017/12/4 0004.
*/
public class RouteUtils {
//获得home模块fragment
public static final String Home_Fragment_Main = “/home/main”;
//获得chat模块fragment
public static final String Chat_Fragment_Main = “/chat/main”;
//获得Recom模块fragment
public static final String Recom_Fragment_Main = “/recom/main”;
//获得Me模块fragment
public static final String Me_Fragment_Main = “/me/main”;
//跳转到登录页面
public static final String Me_Login = “/me/main/login”;
//跳转到eventBus数据接收页面
public static final String Me_EventBus = “/me/main/EventBus”;
//跳转到TextOne数据接收页面
public static final String Me_TextOne = “/me/main/TextOne”;
//跳转到Test公用页面
public static final String Me_Test = “/me/main/Test”;
//路由拦截
public static final String Me_Test2 = “/me/main/Test2”;
//跳转到webview页面
public static final String Me_WebView = “/me/main/WebView”;
//跳转到依赖注入页面
public static final String Me_Inject = “/me/main/Inject”;
/**
- 依赖注入使用,注意:必须实现SerializationService进行注册,
*/
public static final String Home_Json_Service = “/huangxiaoguo/json”;
//跳转ForResult
public static final String Chat_ForResult = “/chat/main/ForResult”;
//模块间服务调用,调用chat模块的接口
public static final String Service_Chat = “/chat/service”;
//路由拦截
public static final String Chat_Interceptor = “/chat/main/Interceptor”;
/**
- 专门的分组,这里就叫做needLogin组,凡是在这个组下的,都会进行登录操作
*/
public static final String NeedLogin_Test3 = “/needLogin/main/Test3”;
}
package tsou.cn.myaroutertest.utils;
import android.support.v4.app.Fragment;
import com.alibaba.android.arouter.launcher.ARouter;
import tsou.cn.lib_base.utils.RouteUtils;
/**
- Created by Administrator on 2017/12/4 0004.
*/
public class FragmentUtils {
public static Fragment getHomeFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(RouteUtils.Home_Fragment_Main).navigation();
return fragment;
}
public static Fragment getChatFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(RouteUtils.Chat_Fragment_Main).navigation();
return fragment;
}
public static Fragment getRecomFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(RouteUtils.Recom_Fragment_Main).navigation();
return fragment;
}
public static Fragment getMeFragment() {
Fragment fragment = (Fragment) ARouter.getInstance().build(RouteUtils.Me_Fragment_Main).navigation();
return fragment;
}
}
package tsou.cn.myaroutertest;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import tsou.cn.myaroutertest.utils.FragmentUtils;
public class MainActivity extends AppCompatActivity {
private ViewPager mMViewPager;
private TabLayout mToolbarTab;
/**
- 图标
*/
private int[] tabIcons = {
R.drawable.tab_home,
R.drawable.tab_weichat,
R.drawable.tab_recommend,
R.drawable.tab_user
};
private String[] tab_array;
private DemandAdapter mDemandAdapter;
private ArrayList fragments = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
// 给viewpager设置适配器
setViewPagerAdapter();
setTabBindViewPager();
setItem();
}
private void initData() {
tab_array = getResources().getStringArray(R.array.tab_main);
fragments.clear();
fragments.add(FragmentUtils.getHomeFragment());
fragments.add(FragmentUtils.getChatFragment());
fragments.add(FragmentUtils.getRecomFragment());
fragments.add(FragmentUtils.getMeFragment());
}
private void initView() {
mMViewPager = (ViewPager) findViewById(R.id.mViewPager);
mToolbarTab = (TabLayout) findViewById(R.id.toolbar_tab);
}
private void setViewPagerAdapter() {
mDemandAdapter = new DemandAdapter(getSupportFragmentManager());
mMViewPager.setAdapter(mDemandAdapter);
}
private void setTabBindViewPager() {
mToolbarTab.setupWithViewPager(mMViewPager);
}
private void setItem() {
/**
- 一定要在设置适配器之后设置Icon
*/
for (int i = 0; i < mToolbarTab.getTabCount(); i++) {
mToolbarTab.getTabAt(i).setCustomView(getTabView(i));
}
}
public View getTabView(int position) {
View view = LayoutInflater.from(this).inflate(R.layout.item_tab, null);
ImageView tab_image = view.findViewById(R.id.tab_image);
TextView tab_text = view.findViewById(R.id.tab_text);
tab_image.setImageResource(tabIcons[position]);
tab_text.setText(tab_array[position]);
return view;
}
/**
- 适配器
*/
public class DemandAdapter extends FragmentStatePagerAdapter {
public DemandAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
}
代码中有注释,切很简单,不会出现什么毛病!如果有小毛病,就clean一下解决
- 跨模块跳转Activity
实现这个Activity跳转的路径。
//跳转到我的模块登录页面
public static final String Me_Login = “/me/main/login”;
ARouter跳转Activity,在这个Activity上加入注解。
@Route(path = RouteUtils.Me_Login)
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
跳转逻辑是
//登录(跨模块跳转Activity)
ARouter.getInstance().build(RouteUtils.Me_Login).navigation();
- 跨模块实现ForResult返回数据(activity中使用)
实现这个Activity跳转的路径。
//跳转ForResult
public static final String Chat_ForResult = “/chat/main/ForResult”;
ARouter跳转Activity,在这个Activity上加入注解。
@Route(path = RouteUtils.Chat_ForResult)
public class ForResultActivity extends AppCompatActivity implements View.OnClickListener {
跳转逻辑是
//跳转ForResult,在fragment中使用不起作用
ARouter.getInstance().build(RouteUtils.Chat_ForResult).navigation(this, 666);
接收数据数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 666:
String name = data.getStringExtra(“name”);
UIUtils.showToast(name + “,resultCode===>” + resultCode);
break;
default:
break;
}
}
返回数据
Intent intent = new Intent();
intent.putExtra(“name”, “ForResult返回的数据”);
setResult(999, intent);
finish();
- 跳转并携带参数和Eventbus夸模块通信
EventBus.getDefault().register(this);
EventBus.getDefault().unregister(this);
@Subscriber(tag = EvenBusTag.GOTO_EVENTBUS)
public void onEvent(String s) {
UIUtils.showToast(s);
}
//跳转到eventBus数据接收页面
public static final String Me_EventBus = “/me/main/EventBus”;
@Route(path = RouteUtils.Me_EventBus)
public class EventBusActivity extends AppCompatActivity implements View.OnClickListener {
// 跳转并携带参数,基本涵盖所以类型传递,具体可以查看Postcard类
//传递过去的值使用getIntent()接收
//在fragment中无法使用ForResult进行夸模块传递数据
//在activity中可以(详细请看LoginActivity)这里的EventBusBean 已经实现了Parcelable接口
EventBusBean eventBusBean = new EventBusBean();
eventBusBean.setProject(“android”);
eventBusBean.setNum(3);
ARouter.getInstance().build(RouteUtils.Me_EventBus)
.withString(“name”, “haungxiaoguo”)
.withLong(“age”, 25)
.withParcelable(“eventbus”, eventBusBean)
.navigation();
@Route(path = RouteUtils.Me_EventBus)
public class EventBusActivity extends AppCompatActivity implements View.OnClickListener {
/**
- eventBus数据接收页面
*/
private TextView mTextView;
/**
- eventBus返回数据
*/
private Button mBtnBackData;
private String name;
private long age;
private EventBusBean eventbus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_bus);
ARouter.getInstance().inject(this);
initData();
initView();
}
private void initData() {
name = getIntent().getStringExtra(“name”);
age = getIntent().getLongExtra(“age”, 0);
eventbus = getIntent().getParcelableExtra(“eventbus”);
}
private void initView() {
mTextView = (TextView) findViewById(R.id.textView);
mBtnBackData = (Button) findViewById(R.id.btn_back_data);
mBtnBackData.setOnClickListener(this);
mTextView.setText(“name=” + name + “,\tage=” + age + “,\tproject=” + eventbus.getProject() +
“,\tnum=” + eventbus.getNum());
}
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.btn_back_data) {
EventBus.getDefault().post(name, EvenBusTag.GOTO_EVENTBUS);
finish();
} else {
}
}
}
- 使用Uri应用内跳转
EventBusBean eventBusBean = new EventBusBean();
eventBusBean.setProject(“android”);
eventBusBean.setNum(3);
Uri testUriMix = Uri.parse(“arouter://tsou.cn.huangxiaoguo/me/main/EventBus”);
ARouter.getInstance().build(testUriMix)
.withString(“name”, “haungxiaoguo”)
.withLong(“age”, 25)
.withParcelable(“eventbus”, eventBusBean)
.navigation();
- 旧版本转场动画
//旧版本转场动画
ARouter.getInstance()
.build(RouteUtils.Me_Test)
.withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
.navigation(getContext());//context上下文不传无效果
- 新版本转场动画
//新版本转场动画
if (Build.VERSION.SDK_INT >= 16) {
ActivityOptionsCompat compat = ActivityOptionsCompat.
makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);
ARouter.getInstance()
.build(RouteUtils.Me_Test)
.withOptionsCompat(compat)
.navigation();
} else {
UIUtils.showToast(“API < 16,不支持新版本动画”);
}
- 通过URL跳转(webview)
//通过URL跳转(webview)
ARouter.getInstance()
.build(RouteUtils.Me_WebView)
.withString(“url”, “file:///android_asset/schame-test.html”)
.navigation();
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
学习分享,共勉
Android高级架构师进阶之路
题外话,我在阿里工作多年,深知技术改革和创新的方向,Android开发以其美观、快速、高效、开放等优势迅速俘获人心,但很多Android兴趣爱好者所需的进阶学习资料确实不太系统,完整。今天我把我搜集和整理的这份学习资料分享给有需要的人
- Android进阶知识体系学习脑图
- Android进阶高级工程师学习全套手册
- 对标Android阿里P7,年薪50w+学习视频
- 大厂内部Android高频面试题,以及面试经历
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-0MgozAfZ-1712704807605)]
[外链图片转存中…(img-kEVayONZ-1712704807605)]
[外链图片转存中…(img-bfvEGLpB-1712704807606)]
[外链图片转存中…(img-MLjrugIa-1712704807606)]
[外链图片转存中…(img-HcrvYMdp-1712704807606)]
[外链图片转存中…(img-BIfDQYEN-1712704807607)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-oME5HS89-1712704807607)]
学习分享,共勉
Android高级架构师进阶之路
题外话,我在阿里工作多年,深知技术改革和创新的方向,Android开发以其美观、快速、高效、开放等优势迅速俘获人心,但很多Android兴趣爱好者所需的进阶学习资料确实不太系统,完整。今天我把我搜集和整理的这份学习资料分享给有需要的人
- Android进阶知识体系学习脑图
[外链图片转存中…(img-4GCXvb48-1712704807607)]
- Android进阶高级工程师学习全套手册
[外链图片转存中…(img-Q6nHihhB-1712704807608)]
- 对标Android阿里P7,年薪50w+学习视频
[外链图片转存中…(img-FpXFK1OM-1712704807608)]
- 大厂内部Android高频面试题,以及面试经历
[外链图片转存中…(img-OWr1iFNH-1712704807608)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-f7JiazQn-1712704807609)]