经过上一篇文章分析ANetwork框架的基础运行方式后,本篇文章准备分析一下MtopSDK的初始化流程,如果大家还不知道Mtop在移动端App里面干啥的建议先读一下《移动API网关
》这篇文章简单了解MtopSDK。
话不多说,直接开始分析先将文件定位到Lmtopsdk/mtop/intf/Mtop;
这个类上:
.field protected static final instanceMap:Ljava/util/Map;
.field final initTask:Lmtopsdk/mtop/global/init/IMtopInitTask;
.field volatile instanceId:Ljava/lang/String;
.field final mtopConfig:Lmtopsdk/mtop/global/MtopConfig;
里面有几个重要的实例属性:
- instanceMap(存放Mtop实例的)
- initTask(初始化任务)
- instanceId(实例ID可能为: OPEN、INNER、PRODUCT)
- mtopConfig(MTOP配置信息)
那Mtop这个类是如何构造的呢?细看之下会发现Mtop只有一个私有的构造方法:
.method private constructor <init>(Ljava/lang/String;Lmtopsdk/mtop/global/MtopConfig;)V
翻译成Java代码大概就是这样:
private Mtop(String instancceId, MtopConfig config){
...
}
MtopConfig稍后再来分析,再继续往下分析Mtop类还有个私有init方法和几个静态instance的方法:
.method private declared-synchronized init(Landroid/content/Context;Ljava/lang/String;)V
.method public static instance(Landroid/content/Context;)Lmtopsdk/mtop/intf/Mtop;
.method public static instance(Landroid/content/Context;Ljava/lang/String;)Lmtopsdk/mtop/intf/Mtop;
.method public static instance(Ljava/lang/String;Landroid/content/Context;)Lmtopsdk/mtop/intf/Mtop;
.method public static instance(Ljava/lang/String;Landroid/content/Context;Ljava/lang/String;)Lmtopsdk/mtop/intf/Mtop;
因为init方法是个私有的,不太可能从外部调用,所以直接先看下几个instance方法。虽然instance有好几个重载形式,但最终都还是调用的instance(Ljava/lang/String;Landroid/content/Context;Ljava/lang/String;)
,简单的翻译成Java代码如下:
public static instance(Context ctx){
instanec(ctx, null, null);
}
public static instance(Context ctx,String ttid){
instanec(null, ctx, ttid);
}
public static instance(String instanceId, Context ctx){
instanec(instanceId, ctx, null);
}
public static instance(String instanceId, Context ctx,String ttid){
}
知道最终的走向后,咱们就直接分析第四个instance方法就行啦,smali代码就不贴了直接转成Java方便阅读:
public static instance(String instanceId, Context ctx,String ttid){
if(instanceId == null){
instanceId = "INNER";
}
Mtop mtop = instanceMap.get(instanceId); //获取mtop实例
if(mtop == null){
synchronized (Mtop.class){
mtop = instanceMap.get(instanceId); //获取mtop实例
if(mtop == null){
Map<String, MtopConfig> mtopConfigs = MtopSetting.mtopConfigMap;
MtopConfig config = mtopConfigs.get(instanceId);
if(config == null){
config = new MtopConfig(instanceId);
}
mtop = new MTop(instanceId, config);
config.mtopInstance = mtop;
//MtopSetting.mtopConfigMap.put(instanceId, config);
instanceMap.put(instanceId, mtop);
}
}
}
if(mtop.isInit){
return mtop;
}
mtop.init(ctx,ttid);
return mtop;
}
上面的instance方法差不多就是创建Mtop实例、调用init方法,所以再来看一个Mtop的构造方法:
.method private constructor <init>(Ljava/lang/String;Lmtopsdk/mtop/global/MtopConfig;)V
...
iput-object p2, p0, Lmtopsdk/mtop/intf/Mtop;->mtopConfig:Lmtopsdk/mtop/global/MtopConfig;
invoke-static {p1}, Lmtopsdk/mtop/global/init/MtopInitTaskFactory;->getMtopInitTask(Ljava/lang/String;)Lmtopsdk/mtop/global/init/IMtopInitTask;
move-result-object v0
iput-object v0, p0, Lmtopsdk/mtop/intf/Mtop;->initTask:Lmtopsdk/mtop/global/init/IMtopInitTask;
....
.end method
Mtop构造方法做了一些实例属性的初始化工作,需要注意的是initTask
这个实例属性的获取是从MtopInitTaskFactory
里面获取的,跟过去看一下,是如何获取IMtopInitTask
的实例的:
public static IMtopInitTask getMtopInitTask(String instanceId){
switch{
case "INNER":
default:
return InnerMtopInitTask();
case "OPEN":
returnn OpenMtopInitTask();
case "PRODUCT":
return ProductMtopInitTask();
}
}
大概意思就是通过不同的instancceId
获取对应的初始化任务。
有了IMtopInitTask
实例后在哪里执行呢?继续分析Mtop的init方法会发现有一段运行IMtopInitTask
的代码:
new-instance v0, Lmtopsdk/mtop/intf/Mtop$1;
invoke-direct {v0, p0}, Lmtopsdk/mtop/intf/Mtop$1;-><init>(Lmtopsdk/mtop/intf/Mtop;)V
invoke-static {v0}, Lmtopsdk/mtop/util/MtopSDKThreadPoolExecutorFactory;->submit(Ljava/lang/Runnable;)Ljava/util/concurrent/Future;
在分析IMtopInitTask
的几个实现类之前,先去分析一下比较重要的类:MtopSetting
,看名字知道专门用来配置Mtop和MtopConfig的,它有个静态属性和几个方法来设置一些配置:
protected static final Map<String, MtopConfig> mtopConfigMap;
public static MapConfig getMtopConfigByID(String instanceId){ }
...
getMtopConfigByID
这个方法会通过instanceId获取MtopConfig的实例,如果没有的话会创建一个新的并且将它放入到mtopConfigMap
中,方便下次获取。其他的方法都是通过getMtopConfigByID
获取Mtop或MtopConfig实例后调用相应的设置项。
经过上面的一翻分析,猜测以下类的主要作用:
- MtopSettings (设置工具类)
- MtopConfig (存在Mtop配置类)
- Mtop (Mtop核心功能类)
- IMtopInitTask (Mtop初始化任务)
现在有人instanceId
就能知道对应的IMtopInitTask
实例来初始化Mtop,下一篇文章再来分析IMtopInitTask
实例,最终完成爬包功能!!
最后欢迎大家关注我的公众号,获取最新的进展。
免责声明: 本文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请读者自负。