使用阿里ARouter路由实现组件化(模块化)开发流程(2),retrofit设计模式

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即可

这里写图片描述

ARouter初始化


在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一下解决

使用ARouter路由实现各种功能


  • 跨模块跳转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移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

学习分享,共勉

Android高级架构师进阶之路

题外话,我在阿里工作多年,深知技术改革和创新的方向,Android开发以其美观、快速、高效、开放等优势迅速俘获人心,但很多Android兴趣爱好者所需的进阶学习资料确实不太系统,完整。今天我把我搜集和整理的这份学习资料分享给有需要的人

  • Android进阶知识体系学习脑图

  • Android进阶高级工程师学习全套手册

  • 对标Android阿里P7,年薪50w+学习视频

  • 大厂内部Android高频面试题,以及面试经历

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-0MgozAfZ-1712704807605)]
[外链图片转存中…(img-kEVayONZ-1712704807605)]
[外链图片转存中…(img-bfvEGLpB-1712704807606)]
[外链图片转存中…(img-MLjrugIa-1712704807606)]
[外链图片转存中…(img-HcrvYMdp-1712704807606)]
[外链图片转存中…(img-BIfDQYEN-1712704807607)]
img

既有适合小白学习的零基础资料,也有适合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)]

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值