本文已首发微信公众号「code小生」,大家可以搜索关注,专注安卓技术分享。
gradle.properties 文件中添加如下代码
#是否需要单独运行某个模块 true:表示某个模块不作为依赖库使用
isSingleCircleModule=true
#isSingleCircleModule=false
isSingleHomeModule=true
#isSingleHomeModule=false
build.gradlebuild.gradle文件配置
if (!isSingleCircleModule.toBoolean()) {
implementation project(path: ':circle')
}
if (!isSingleHomeModule.toBoolean()){
implementation project(path: ':home')
}
并注释掉原来的依赖
// implementation project(path: ':circle')
// implementation project(path: ':home')
build.gradlecircle模块下build.gradle文件最顶部改动如下:
//plugins {
// id 'com.android.library'
//}
if (isSingleCircleModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
在home模块下build.gradle文件最顶部改动如下:
//plugins {
// id 'com.android.library'
//}
if (isSingleHomeModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
Sync Project with Gradle Files 等待编译完成,可看到如下状态:
这个时候我们选择其中一个module运行,会发现报错如下:
Could not identify launch activity: Default Activity not found
Error while Launching activity
很明显,我们都知道Android程序的主入口是从清单文件配置的,但我们的各module都还没有做这个工作。
在circle模块下的清单文件中,配置如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gs.circle">
<application
android:allowBackup="true"
android:icon="@mipmap/app_icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".CircleActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
其中的配置完清单文件,运行后发现桌面会多出来一个 APP icon,打开只有一个页面,就是我们的icon、label以及theme都可以定义在baselib中,这样我们任何 module 配置的时候就可以直接引用,而无需各自复制一份了;除此之外,values文件夹下的东西都可以移动到baselib下,方便其他模块引用,这也就是baselib模块的作用,如果你要细分,还可以j将公共资源放在一个独立的模块里,这个模块通常叫做:commonlib,具体情况而定。
circlemodule的主页面。home模块的清单配置就不展示了,下面看下效果:
这个时候再切回去运行app模块,如果发现有问题,先卸载再运行就ok了。但是会有一个问题,原来可以跳转其他模块的功能,现在跳转不了了,这其实很正常,因为在组件化开发模式下,每个 module 都是独立的app,所以肯定不能直接跳转过去。
那如何实现正常跳转呢?
需要两步,将gradle.properties中的代码修改为如下:
#isSingleCircleModule=true
isSingleCircleModule=false
#isSingleHomeModule=true
isSingleHomeModule=false
接着将circle和home模块的清单文件中的 application属性和默认启动配置项删掉,然后再运行就 ok 了。
如果想将其中一个作为依赖库使用,那么就指匠情挑设置为false即可。
关于组件之间 AndroidManifest 合并问题
其实这个可以在正式打包的时候,注释掉module中的相关代码即可,毕竟是在组件模式。那有没有办法解决每次都要注释的问题呢?答案是yes.
大致思路如下:
在可独立运行的module的res->main文件夹下新建一个文件夹(命名自定义),然后将对应的清单文件复制一份,名称不需要修改,内容的差别就是前面提到的,去掉application属性和默认启动配置项。<br/> 接着在对应 module 的 build.gradle 中指定表单的路径,代码如下:
sourceSets {
main {
if (isSingleCircleModule.toBoolean()) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
这样在不同的开发模式下就会读取到不同的 AndroidManifest.xml ,然后我们需要修改这两个表单的内容以为我们不同的开发模式服务。
build.gradle文件中添加下面这行代码:
classpath 'com.alibaba:arouter-register:1.0.2'
在app模块的build.gradle文件下,配置改动如下:
plugins {
id 'com.android.application'
id 'com.alibaba.arouter' // 拦截器必须配置
}
配置完这两步,按照惯例,该是编译了。
为了演示,我这里在app下新建一个名为LoginActivity的页面,作业登录拦截后跳转的页面,页面内容只有一个提示文本,这里补贴代码。
然后分别在宿主模块app、功能模块circle和home中去做跳转登录页面,看看我们的拦截器是否起到了拦截作用,下面开始定义拦截器。
要独立运行某个模块,这里就不再赘述了,大家自行修改配置即可。拦截器完整代码如下:
/**
* Description: 登录拦截器
* Date: 2021/10/9 10:42
* <p>
* 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
* * <p>
* * priority 数值越小权限越高
*/
@Interceptor(priority = 2, name = "登录ARouter拦截器")
public class LoginInterceptor implements IInterceptor {
private Context mContext;
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
boolean isLogin = mContext.getSharedPreferences("arouterdata", mContext.MODE_PRIVATE).getBoolean("isLogin", false);
if (isLogin) {
callback.onContinue(postcard);
} else {
switch (postcard.getPath()) {
// 需要登录的拦截下来
case ARouterPath.APP_MY_INFO:
ARouter.getInstance().build(ARouterPath.LOGIN_PAGE).with(postcard.getExtras()).navigation();
break;
default:
callback.onContinue(postcard);
break;
}
}
}
/**
* 拦截器的初始化,会在sdk初始化的时候调用该方法,仅会调用一次
*
* @param context
*/
@Override
public void init(Context context) {
mContext = context;
}
}
拦截器初始化需要重新安装才会生效,这点要注意。拦截器是不需要我们手动显示调用的,而是框架通过注解来使用的,所以我们只需要写好逻辑代码即可。
以上代码可以实现模块内和跨模块跳转拦截,本地的登录状态我这里没有处理逻辑,所以每次都会被拦截到。下面看效果:
演示效果模拟进入MyInfoActivity页面时需要先登录,分别从三个模块做了跳转演示。
本文全部代码已打包:关注微信公众号code小生回复arouter
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/
我正在学习如何在我的Ruby代码中使用Module.prepend而不是alias_method_chain,我注意到有些人使用send调用它(example):ActionView::TemplateRenderer.send(:prepend,ActionViewTemplateRendererWithCurrentTemplate)而其他人直接调用它(example):ActionView::TemplateRenderer.prepend(ActionViewTemplateRendererWithCurrentTemplate)而且,虽然我还没有看到任何人使用这种风格,但我从
GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'
是否有可能:before_filter:authenticate_user!||:authenticate_admin! 最佳答案 before_filter:do_authenticationdefdo_authenticationauthenticate_user!||authenticate_admin!end 关于ruby-on-rails-before_filter运行多个方法,我们在StackOverflow上找到一个类似的问题: https://