隨著業(yè)務(wù)復(fù)雜的和開(kāi)發(fā)人員的增多灯变,代碼管理和協(xié)同開(kāi)發(fā)逐漸成為開(kāi)發(fā)過(guò)程中的瓶頸逗爹。好在Android 自己支持了分模塊開(kāi)發(fā)飒硅。搭建自己的模塊化開(kāi)發(fā)需要如下步驟:
- 搭建自己的私有倉(cāng)庫(kù)徒蟆,存儲(chǔ)各個(gè)模塊胎挎。
搭建私有倉(cāng)庫(kù)推薦nexus,搭建方法百度一下沟启。上傳AAR到倉(cāng)庫(kù)的方法如下:
apply plugin: 'maven'
def libVersion;
def libArtifactId;
def libGroupId = 'cn.daily.android';
def libDescription = 'lib';
task readProperty() {
File file = project.file("publish.properties");
if (!file.exists()) {
file.createNewFile();
Writer writer = file.newWriter();
writer.writeLine("groupId=cn.daily.android");
writer.writeLine("artifactId=" + project.name);
writer.writeLine("version=0.0.1-SNAPSHOT");
writer.writeLine("description=默認(rèn)描述,請(qǐng)根據(jù)情況修改相應(yīng)字段");
writer.close();
throw new FileNotFoundException("請(qǐng)修改" + file.getPath() + "\n中的默認(rèn)信息!\n注意只提醒一次,否則使用默認(rèn)!");
}
Properties properties = new Properties();
InputStream inputStream = file.newInputStream();
properties.load(inputStream);
libVersion = properties.getProperty("version");
libArtifactId = properties.getProperty("artifactId");
libGroupId = properties.getProperty("groupId")
libDescription = properties.getProperty("description")
inputStream.close();
}
//上傳AAR犹菇、source德迹、JavaDoc腳本
uploadArchives {
repositories {
//配置倉(cāng)庫(kù)地址和模塊相關(guān)信息
mavenDeployer {
snapshotRepository(url: 'http://替換成你的倉(cāng)庫(kù)地址/nexus/content/repositories/snapshots') {
authentication(userName: '替換成你的nexus用戶名', password: '替換成你的Nexus倉(cāng)庫(kù)密碼')
}
repository(url: 'http://替換成你的倉(cāng)庫(kù)地址/nexus/content/repositories/releases') {
authentication(userName: '替換成你的nexus用戶名', password: '替換成你的Nexus倉(cāng)庫(kù)密碼')
}
pom.project {
version libVersion
artifactId libArtifactId
groupId libGroupId
description libDescription
packaging 'aar'
}
}
//創(chuàng)建源文件任務(wù)
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
//上傳文件
artifacts {
archives file(project.name + '.aar')
archives androidSourcesJar
}
}
}
- 構(gòu)建自己的路由讓各個(gè)模塊可以聯(lián)動(dòng)。
各個(gè)模塊是相互獨(dú)立揭芍,Activity之間的跳轉(zhuǎn)只能通過(guò)隱式調(diào)用胳搞。通過(guò)packageManager的方法 queryIntentActivities來(lái)查找滿足跳轉(zhuǎn)的Activity。詳細(xì)代碼如下:
public class Nav {
private Context mContext;
private Intent mIntent;
private Fragment mFragment;
private Bundle mBundle;
private boolean isNeedLogin = false;
private String mAction;
private List<String> mCategories;
private static List<Interceptor> sInterceptors = new ArrayList<>();
private Nav(Context context) {
mContext = context;
mIntent = new Intent();
mIntent.setAction(Intent.ACTION_VIEW);
}
private Nav(Fragment fragment) {
this(fragment.getContext());
mFragment = fragment;
}
public static Nav with(Context context) {
return new Nav(context);
}
public static Nav with(Fragment fragment) {
return new Nav(fragment);
}
public static void addInterceptor(Interceptor interceptor) {
sInterceptors.add(interceptor);
}
public boolean to(String url) {
return to(url, -1);
}
public boolean to(String url, int requestCode) {
if (TextUtils.isEmpty(url)) {
if (BuildConfig.DEBUG) {
throw new NullPointerException("url");
}
return false;
}
return to(Uri.parse(url), requestCode);
}
public Nav setExtras(Bundle bundle) {
mBundle = bundle;
return this;
}
public Nav needLogin(boolean isNeedLogin) {
this.isNeedLogin = isNeedLogin;
return this;
}
public Nav setAction(String action) {
mAction = action;
return this;
}
public Nav addCategory(String category) {
if (mCategories == null) {
mCategories = new ArrayList<>();
}
mCategories.add(category);
return this;
}
public Nav removeCategory(String category) {
if (mCategories != null && mCategories.size() > 0) {
mCategories.remove(category);
}
return this;
}
public boolean to(Uri uri, int requestCode) {
if (uri == null) {
if (BuildConfig.DEBUG) {
throw new NullPointerException("uri");
}
return false;
}
if (!TextUtils.isEmpty(mAction)) {
mIntent.setAction(mAction);
}
if (mCategories != null && mCategories.size() > 0) {
for (int i = 0; i < mCategories.size(); i++) {
mIntent.addCategory(mCategories.get(i));
}
}
if (mBundle != null) {
mIntent.putExtras(mBundle);
}
if (sInterceptors != null) {
for (int i = 0; i < sInterceptors.size(); i++) {
uri = sInterceptors.get(i).before(uri);
}
}
mIntent.setData(uri.normalizeScheme());
return parseIntent(requestCode);
}
private boolean parseIntent(int requestCode) {
List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentActivities
(mIntent, PackageManager.MATCH_ALL);
try {
if (resolveInfos == null || resolveInfos.size() == 0) {
throw new ActivityNotFoundException("Not match any Activity:" + mIntent.toString());
} else {
ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
//優(yōu)先匹配應(yīng)用自己的Activity
for (int i = 0; i < resolveInfos.size(); i++) {
if (resolveInfos.get(i).activityInfo.packageName.contains(mContext
.getPackageName())) {
activityInfo = resolveInfos.get(i).activityInfo;
break;
}
}
mIntent.setClassName(activityInfo.packageName, activityInfo.name);
}
startIntent(mIntent, requestCode);
return true;
} catch (ActivityNotFoundException e) {
e.printStackTrace();
return false;
}
}
private void startIntent(Intent intent, int requestCode) {
if (mFragment != null) {
mFragment.startActivityForResult(intent, requestCode);
} else if (mContext instanceof Activity) {
((Activity) mContext).startActivityForResult(intent, requestCode);
} else {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
}
private boolean isLogin(Context context) {
return false;
}
public interface Interceptor {
Uri before(Uri uri);
}
}