テレビのAndroidのパワーはホット更新QQスペース技術であります

直接コードに

 

 

 

 

 

 

 

 

パッケージcom.enjoy.patch。

輸入android.content.Context;
輸入android.os.Build;
輸入android.util.Log;

輸入java.io.BufferedInputStreamの。
輸入java.io.BufferedOutputStream。
インポートのjava.io.File;
輸入java.io.FileOutputStreamは、
インポートにjava.io.IOException;
インポートをjava.lang.reflect.Field;
インポートにjava.lang.reflect.InvocationTargetException;
輸入java.lang.reflect.Methodオブジェクト。
輸入はjava.util.ArrayList;
輸入はjava.util.List;


パブリッククラスEnjoyFix {

プライベート静的最終文字列タグ=「EnjoyFix」。

プライベート静的ファイルinitHack(コンテキスト・コンテキスト){

ファイルhackDir = context.getDir(Context.MODE_PRIVATEを"ハック")。
hackFileファイル=新しいファイル(hackDir、 "hack.jar");
(!hackFile.exists()){場合
にBufferedInputStreamは= nullです。
BufferedOutputStreamが、OS = NULL;
{しようとは
=新しいBufferedInputStreamを(。context.getAssets()オープン(+ "ハック"である
"の.jarを"));
OS =新なBufferedOutputStream(新しいのFileOutputStream(hackFile));
バイト[]バッファ=新しいバイト[4096];
int型のlen;
(!(LEN = is.read(バッファ))= -1){一方
os.write(バッファ、0、LEN)。
}
}キャッチ(IOExceptionを電子){
e.printStackTrace();
} {ついに
(!= nullがある)場合には{
{みてください
)(is.closeを。
}キャッチ(IOExceptionを電子){
e.printStackTrace();
}
}
もし(!OS = NULL){
試み{
にos.close()。
}キャッチ(IOExceptionを電子){
e.printStackTrace();
}
}
}
}
hackFileを返します。

}

パブリック静的ボイドinstallpatchは(コンテキスト・コンテキスト、ファイルパッチ){
ファイルhackFile = initHack(コンテキスト)。
ClassLoaderクラスローダ= context.getClassLoader()。
一覧<ファイル>ファイル=新しいArrayListを<>();
IF(patch.exists()){
files.add(パッチ)。
}
files.add(hackFile)。
ファイルdexOptDir = context.getCacheDir();
試す{
Log.i( "TAG"、 "Build.VERSION.SDK_INT" + Build.VERSION.SDK_INT)。
// 23 6.0及以上
であれば(Build.VERSION.SDK_INT> = Build.VERSION_CODES.M){
V23.install(クラスローダ、ファイル、dexOptDir)。
}そうであれば(Build.VERSION.SDK_INT> = Build.VERSION_CODES.KITKAT){
V19.install(クラスローダ、ファイル、dexOptDir)。
}他{//> = 14
V14.install(クラスローダ、ファイル、dexOptDir)。
}
}キャッチ(例外e){
e.printStackTrace();
}
}


プライベート静的最終的なクラスV23が{

プライベート静的ボイドは、(クラスローダローダ、リスト<ファイル> additionalClassPathEntries、インストール
ファイルoptimizedDirectory)
はIllegalArgumentException、IllegalAccessExceptionが、スロー
持たないNoSuchFieldException、にInvocationTargetException、ないNoSuchMethodException、
にIOException {
//找到pathlistに
フィールドpathListField = SharedReflectUtils.findField(ローダ、 "pathlistに");
DexPathList = pathListField.getオブジェクト(ローダー);

ArrayListを<にIOException> =新しい新しいsuppressedExceptionsのArrayList <>();
//見つけてpathlistにからmakePathElementsメソッドを実行
//要素[]作成するためのパッチを取得します
(オブジェクト[] =のmakePathElementsオブジェクトをdexPathList、
ArrayListの新しい新しい<>(additionalClassPathEntries)、optimizedDirectory、
suppressedExceptions);

//合成アレイ得原dexElementsのmakePathElementsと
SharedReflectUtils.expandFieldArray(dexPathList、 "dexElements"、オブジェクト);
IF(suppressedExceptions.size()> 0){
用(IOExceptionを電子:suppressedExceptions){
Log.w(TAG、 "makePathElementの例外"、E)。
Eを投げます。
}

}
}

/ **
*把DEX转化为要素数组
* /
プライベート静的オブジェクト[] makePathElements(
dexPathList、ArrayListを<ファイル>ファイル、ファイルoptimizedDirectory、オブジェクト
のArrayList <にIOException> suppressedExceptionsを)
投げるIllegalAccessExceptionが、InvocationTargetExceptionが、ないNoSuchMethodException {
//通过阅读android6,7,8,9源码、都makePathElements方法存在
方法makePathElements = SharedReflectUtils.findMethod(dexPathList、 "makePathElements"、
List.class、File.class、
List.class)。
リターン(オブジェクト[])makePathElements.invoke(dexPathList、ファイル、optimizedDirectory、
suppressedExceptions)。
}
}

プライベート静的最終的なクラスV19 {

プライベート静的ボイドは、(クラスローダローダを、リスト<ファイル> additionalClassPathEntries、インストール
ファイルoptimizedDirectoryは)
はIllegalArgumentException、IllegalAccessExceptionが、スロー
持たないNoSuchFieldException、にInvocationTargetException、ないNoSuchMethodException、
にIOException {
フィールドpathListField = SharedReflectUtils.findField(ローダ、 "pathlistに"を);
オブジェクトdexPathList = pathListField.get(ローダ)。
ArrayListの<にIOException> suppressedExceptions =新しいのArrayList <IOExceptionを>();
SharedReflectUtils.expandFieldArray(dexPathList、 "dexElements"、
makeDexElements(dexPathList、
新しいのArrayList <ファイル>(additionalClassPathEntries)、optimizedDirectory、
suppressedExceptions));
IF(suppressedExceptions.size()> 0){
ため(のIOExceptionのE:suppressedExceptions){
Log.w(TAG、 "makeDexElementの例外"、E)。
Eを投げます。
}
}
}

プライベート静的オブジェクト[] makeDexElements(
オブジェクトdexPathList、のArrayList <ファイル>ファイル、ファイルoptimizedDirectory、
のArrayList <にIOException> suppressedExceptions)は
IllegalAccessExceptionが、にInvocationTargetException、ないNoSuchMethodException {スロー
方法makeDexElements = SharedReflectUtils.findMethod(dexPathListを、 "makeDexElements"、
ArrayList.class、ファイル.class、
ArrayList.class)。


リターン(オブジェクト[])makeDexElements.invoke(dexPathList、ファイル、optimizedDirectory、
suppressedExceptions)。
}
}

/ **
* 14、15、16、17、18
* /
プライベート静的最終クラスV14 {


プライベート静的ボイドが(クラスローダローダを、一覧<ファイル> additionalClassPathEntries、インストール
ファイルoptimizedDirectoryは)
はIllegalArgumentException、IllegalAccessExceptionが、スロー
持たないNoSuchFieldException、InvocationTargetExceptionが、ないNoSuchMethodException {

フィールドpathListField = SharedReflectUtils.findField(ローダー、 "pathlistにします");
オブジェクトdexPathList = pathListField.get(ローダ)。

SharedReflectUtils.expandFieldArray(dexPathList、 "dexElements"、
makeDexElements(dexPathList、
新しいのArrayList <ファイル>(additionalClassPathEntries)、optimizedDirectory));
}

プライベート静的オブジェクト[] makeDexElements(
オブジェクトdexPathList、のArrayList <ファイル>ファイル、ファイルoptimizedDirectory)は
IllegalAccessExceptionが、にInvocationTargetException、スロー
ないNoSuchMethodException {
法makeDexElements =
SharedReflectUtils.findMethod(dexPathList、 "makeDexElements"を、ArrayList.class、
File.class)。
リターン(オブジェクト[])makeDexElements.invoke(dexPathList、ファイル、optimizedDirectory)。
}
}

}
----------------------------------------------- -------------------------------------------------- --------------------------------
com.enjoy.patchパッケージ; 

インポートjava.lang.reflect.Array;
をjava.lang.reflect.Fieldなどのインポート、
インポートjava.lang.reflect.Methodオブジェクト、
インポートjava.util.Arrays;

/ **
*反射ツール
* /
{クラスSharedReflectUtilsパブリック


/ **
*親クラス名のプロパティを見つけるインスタンスから
*
* @paramインスタンス
* @param名
* @return
*持たないNoSuchFieldException @throws
* /
パブリック静的フィールドは、FindFieldは(文字列名、インスタンスオブジェクト){持たないNoSuchFieldExceptionをスロー
するための(クラスclazz = instance.getClass()<?>; clazz = nullを;! clazz = clazz.getSuperclass()){
試み{
//(親を含まない)現在のクラスのプロパティを見つけます
フィールドフィールド= clazz.getDeclaredField(名);

(!field.isAccessible()){もし
field.setAccessible(真の);
}
戻りフィールドと
}キャッチ(ないNoSuchFieldException電子){
//無視して検索し、次
}
}
新しい持たないNoSuchFieldException( "フィールド" +名前+ + instance.getClass() "には見られない")を投げます。
}

/ **
*从インスタンス到其父类找名前方法
*
* @paramインスタンス
* @param名
* @return
*ないNoSuchFieldExceptionを@throws
/ *
パブリック静的メソッドfindMethodは(<?>インスタンスオブジェクト、文字列の名前は、クラス... parameterTypesと)
ないNoSuchMethodException {スロー
(<?>; clazz = NULL;!clazz = clazz.getSuperclass()クラスclazz = instance.getClass())について{
{試す
メソッド方法= clazz.getDeclaredMethod(名前、parameterTypesパラメータ)を、

(!method.isAccessible()){もし
method.setAccessible(真の);
}

戻り方法。
}キャッチ(ないNoSuchMethodException電子){
//無視して次の検索
}
}
新しいないNoSuchMethodException( "メソッド"を投げる
+名前
+ "パラメータで"
+は、Arrays.asList(parameterTypesパラメータ)
+ + instance.getClass()) "で見つかりません"。
}


/ **
* @paramインスタンス
* @paramのフィールド名
* @param fixs补丁的要素数组
* @throwsないNoSuchFieldException
* @throwsはIllegalArgumentException
* @throws IllegalAccessExceptionが
* /
パブリック静的ボイドexpandFieldArray(インスタンスオブジェクト、文字列フィールド名は、[] fixsオブジェクト)
スロー持たないNoSuchFieldException、はIllegalArgumentException、IllegalAccessExceptionが{
//拿到ローダ中的dexelements数组
フィールドjlrField = findField(例えば、フィールド名)。
//古い要素[]
オブジェクト[] =古いjlrField.get(インスタンス)([]オブジェクト)。


//合并后的数组
オブジェクト[]れたnewElements =(オブジェクト[])Array.newInstance(old.getClass()getComponentType()。
old.length +のfixs.length)。

//先拷贝新数组
System.arraycopyの(fixs、0たnewElements、0、fixs.length)。
System.arraycopyの(古い、0、newElementsに、fixs.length、old.length)。

//修改クラスローダ中pathlistに的dexelements
jlrField.set(例えば、たnewElements)。
}


}



おすすめ

転載: www.cnblogs.com/xiaoxiaing/p/11598877.html