-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plugin uninstall functionality optimized for synchronizing multiple p… #199
Changes from 2 commits
e06f331
f2d71d5
75e9d4e
d2f85fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,9 @@ public void remove(String pn) { | |
JSONHelper.remove(mJson, i); | ||
} | ||
} | ||
if (mMap.containsKey(pn)) { | ||
mMap.remove(pn); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 是不是也应该清掉mList? |
||
} | ||
|
||
public PluginInfo get(String pn) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ | |
import com.qihoo360.loader2.CertUtils; | ||
import com.qihoo360.loader2.MP; | ||
import com.qihoo360.loader2.PluginNativeLibsHelper; | ||
import com.qihoo360.mobilesafe.api.Tasks; | ||
import com.qihoo360.mobilesafe.utils.pkg.PackageFilesUtil; | ||
import com.qihoo360.replugin.RePlugin; | ||
import com.qihoo360.replugin.RePluginEventCallbacks; | ||
|
@@ -200,7 +201,19 @@ private boolean verifySignature(PackageInfo pi, String path) { | |
} | ||
|
||
private boolean checkVersion(PluginInfo instPli, PluginInfo curPli) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 建议改下返回值为int,-1为instPli小于curPli,1为instPli大于curPli,0为两者相等,这样就不必再checkVersion中做set操作了 |
||
if (instPli.getVersion() <= curPli.getVersion()) { | ||
// 支持插件同版本覆盖安装? | ||
// 若现在要安装的,与之前的版本相同,则覆盖掉之前的版本; | ||
if (instPli.getVersion() == curPli.getVersion()) { | ||
if (LogDebug.LOG) { | ||
LogDebug.d(TAG, "isSameVersion: same version. " + | ||
"inst_ver=" + instPli.getVersion() + "; cur_ver=" + curPli.getVersion()); | ||
} | ||
instPli.setIsPendingCover(true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 建议改下返回值为int,-1为instPli小于curPli,1为instPli大于curPli,0为两者相等,这样就不必再checkVersion中做set操作了 |
||
return true; | ||
} | ||
|
||
// 若现在要安装的,比之前的版本还要旧,则忽略更新; | ||
if (instPli.getVersion() < curPli.getVersion()) { | ||
if (LogDebug.LOG) { | ||
LogDebug.e(TAG, "checkVersion: Older than current, install fail. pn=" + curPli.getName() + | ||
"; inst_ver=" + instPli.getVersion() + "; cur_ver=" + curPli.getVersion()); | ||
|
@@ -209,9 +222,9 @@ private boolean checkVersion(PluginInfo instPli, PluginInfo curPli) { | |
} | ||
|
||
// 已有“待更新版本”? | ||
// 若现在要安装的,比“待更新版本”还要旧(或相同),则也可以忽略 | ||
// 若现在要安装的,比“待更新版本”还要旧,则也可以忽略 | ||
PluginInfo curUpdatePli = curPli.getPendingUpdate(); | ||
if (curUpdatePli != null && instPli.getVersion() <= curUpdatePli.getVersion()) { | ||
if (curUpdatePli != null && instPli.getVersion() < curUpdatePli.getVersion()) { | ||
if (LogDebug.LOG) { | ||
LogDebug.e(TAG, "checkVersion: Older than updating plugin. Ignore. pn=" + curPli.getName() + "; " + | ||
"cur_ver=" + curPli.getVersion() + "; old_ver=" + curUpdatePli.getVersion() + "; new_ver=" + instPli.getVersion()); | ||
|
@@ -272,8 +285,14 @@ private void updateOrLater(PluginInfo curPli, PluginInfo instPli) { | |
if (LogDebug.LOG) { | ||
LogDebug.w(TAG, "updateOrLater: Plugin is running. Later. pn=" + curPli.getName()); | ||
} | ||
instPli.setIsThisPendingUpdateInfo(true); | ||
curPli.setPendingUpdate(instPli); | ||
if (instPli.getVersion() > curPli.getVersion()) { | ||
// 高版本升级 | ||
instPli.setIsThisPendingUpdateInfo(true); | ||
curPli.setPendingUpdate(instPli); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 如果已经要做升级了,应该需要做一次setPendingCover(null)和setPendingDelete(null),之后的操作覆盖之前的。并打个Log出来 |
||
} else if (instPli.getVersion() == curPli.getVersion()){ | ||
// 同版本覆盖 | ||
curPli.setPendingCover(instPli); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 同理,应该setPendingDelete(null),但无需setPendingUpdate,因为在updatePendingUpdate时就已经return了(建议加个注释说明一下) |
||
} | ||
} else { | ||
if (LogDebug.LOG) { | ||
LogDebug.i(TAG, "updateOrLater: Not running. Update now! pn=" + curPli.getName()); | ||
|
@@ -340,16 +359,16 @@ private boolean updateIfNeeded(PluginInfo curInfo) { | |
LogDebug.d(TAG, "updateIfNeeded: delete plugin. pn=" + curInfo.getName()); | ||
} | ||
|
||
// 移除插件及其已释放的Dex、Native库等文件 | ||
PackageFilesUtil.forceDelete(curInfo.getPendingDelete()); | ||
mList.remove(curInfo.getName()); | ||
return true; | ||
// 移除插件及其已释放的Dex、Native库等文件并向各进程发送广播,同步更新 | ||
return uninstallNow(curInfo.getPendingDelete()); | ||
|
||
} else if (curInfo.isNeedUpdate()) { | ||
// 需要更新插件?那就直接来 | ||
updateNow(curInfo, curInfo.getPendingUpdate()); | ||
return true; | ||
|
||
} else if (curInfo.isNeedCover()) { | ||
updateNow(curInfo, curInfo.getPendingCover()); | ||
return true; | ||
} else { | ||
// 既不需要删除也不需要更新 | ||
if (LogDebug.LOG) { | ||
|
@@ -360,17 +379,46 @@ private boolean updateIfNeeded(PluginInfo curInfo) { | |
} | ||
|
||
private void updateNow(PluginInfo curInfo, PluginInfo newInfo) { | ||
// 删除旧版本插件,不管是不是p-n的,且清掉Dex和Native目录 | ||
delete(curInfo); | ||
final boolean covered = newInfo.getIsPendingCover(); | ||
if (covered) { | ||
move(curInfo, newInfo); | ||
} else { | ||
// 删除旧版本插件,不管是不是p-n的,且清掉Dex和Native目录 | ||
delete(curInfo); | ||
} | ||
|
||
newInfo.setType(PluginInfo.TYPE_EXTRACTED); | ||
if (LogDebug.LOG) { | ||
LogDebug.i(TAG, "updateNow: Update. pn=" + curInfo.getVersion() + | ||
"; cur_ver=" + curInfo.getVersion() + "; update_ver=" + newInfo.getVersion()); | ||
} | ||
|
||
curInfo.update(newInfo); | ||
curInfo.setPendingUpdate(null); | ||
if (covered) { | ||
curInfo.setPendingCover(null); | ||
} else { | ||
curInfo.update(newInfo); | ||
curInfo.setPendingUpdate(null); | ||
} | ||
} | ||
|
||
private void move(@NonNull PluginInfo curPi, @NonNull PluginInfo newPi) { | ||
try { | ||
FileUtils.copyFile(newPi.getApkFile(), curPi.getApkFile()); | ||
FileUtils.copyFile(newPi.getDexFile(), curPi.getDexFile()); | ||
FileUtils.copyFile(newPi.getNativeLibsDir(), curPi.getNativeLibsDir()); | ||
} catch (IOException e) { | ||
if (LogRelease.LOGR) { | ||
e.printStackTrace(); | ||
} | ||
} finally { | ||
try { | ||
FileUtils.forceDelete(newPi.getApkFile().getParentFile()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 建议这么写,这样减少歧义: File parentDir = newPi.getApkFile().getParentFile();
FileUtils.forceDelete(parentDir); |
||
} catch (IOException e) { | ||
if (LogRelease.LOGR) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private void delete(@NonNull PluginInfo pi) { | ||
|
@@ -436,14 +484,25 @@ private boolean uninstallNow(PluginInfo info) { | |
// 1. 移除插件及其已释放的Dex、Native库等文件 | ||
PackageFilesUtil.forceDelete(info); | ||
|
||
// 2. 给各进程发送广播,同步更新 | ||
Intent intent = new Intent(PluginInfoUpdater.ACTION_UNINSTALL_PLUGIN); | ||
intent.putExtra("obj", info); | ||
IPC.sendLocalBroadcast2AllSync(RePluginInternal.getAppContext(), intent); | ||
|
||
// 3. 保存插件信息到文件中 | ||
// 2. 保存插件信息到文件中 | ||
mList.remove(info.getName()); | ||
mList.save(mContext); | ||
|
||
// 3. 给各进程发送广播,同步更新 | ||
final Intent intent = new Intent(PluginInfoUpdater.ACTION_UNINSTALL_PLUGIN); | ||
intent.putExtra("obj", info); | ||
// 注意:attachBaseContext内部获取getApplicationContext会为空,则此情况仅在UI线程进行更新 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这块儿的注释还是不够清晰。建议改为: “注意:若在attachBaseContext中调用此方法,则由于此时getApplicationContext为空,导致发送广播时会出现空指针异常。则应该Post一下,待getApplicationContext有值后再发送广播” |
||
if (RePluginInternal.getAppContext().getApplicationContext() != null) { | ||
IPC.sendLocalBroadcast2AllSync(RePluginInternal.getAppContext(), intent); | ||
} else { | ||
Tasks.init(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RePlugin.onCreate内部也调用了Tasks.init,不如挪到attachBaseContext中靠前位置,这样这里就不用调用了。 |
||
Tasks.post2UI(new Runnable() { | ||
@Override | ||
public void run() { | ||
IPC.sendLocalBroadcast2All(RePluginInternal.getAppContext(), intent); | ||
} | ||
}); | ||
} | ||
return true; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
建议去掉Added by 字样,因为开源后的PR可以体现改动点。