准备工作:安装perl工具 ActivePerl 5.14.1 Build 1401
新建文件夹目录:
updata-jar-dex.v2.0
|--------lib / dx.jar ( 从这个目录获取:\Android\sdk\build-tools\android-5.1\lib)
|--------jar / framework.jar services.jar (这个目录下放原始的目标文件:framework.jar services.jar)
|--------update-jar-dex.pl
|--------services-update.bat
|--------framework-update.bat
|--------services-classes.txt
|--------framework-classes.txt
1、update-jar-dex.pl
源码如下:
#! /usr/bin/perl -w
## update dex by repacking class jar then do dex
#
#
use Getopt::Long;
use File::Basename qw (basename);
use File::Copy qw( copy );
use FindBin qw( $Bin );
sub usage;
$MYROOT = $Bin;
$DXJAR = "\"$MYROOT/lib/dx.jar\"";
GetOptions("r|root=s", \$class_out_root, "c|class=s", \$class_list,
"j|jar=s", \$class_jar, "o|output=s", \$dex_out,
"h|help", \$help) or die "invalid parameters!\n";
if ($help) {
usage;
exit 0;
}
# ensure parameter
unless ($class_out_root) {
print "ERROR! no '-r' parameter.\n";
usage;
exit 1;
}
unless ($class_list) {
print "ERROR! no '-c' parameter.\n";
usage;
exit 1;
}
unless ($class_jar) {
print "ERROR! no '-j' parameter.\n";
usage;
exit 1;
}
unless ($dex_out) {
print "ERROR! no '-o' parameter.\n";
usage;
exit 1;
}
# ensure file and dir
unless(-d $class_out_root) {
print "ERROR! can't acces root dir '$class_out_root'.\n";
exit 1;
}
unless (-f $class_list) {
print "ERROR! can't read class list file '$class_list'.\n";
exit 1;
}
if ($class_jar =~ /.jar$/) {
unless (-f $class_jar) {
print "ERROR! can't find the origin jar '$class_jar'.\n";
exit;
}
} else {
$class_jar = $class_jar . ".jar";
unless (-f "$MYROOT/jar/$class_jar") {
print "ERROR! can't find the origin jar 'jar/$class_jar'.\n";
exit 1;
}
$class_jar = "$MYROOT/jar/$class_jar";
}
# remove classes.jar if exists
my $tmp_jar = "$MYROOT/classes.jar";
unlink $tmp_jar if -f $tmp_jar;
# unzip .jar
my $CLSFLD = "classes";
my $TMP_CLS_DIR = "$MYROOT/$CLSFLD";
if (-d $CLSFLD) {
print "cleanup intermediates...\n";
if ($^O =~ /MSWin32/) {
qx { rd /S /Q $CLSFLD } ;
} else {
qx { rm -rf $CLSFLD };
}
}
print "extract .class files...\n";
mkdir $TMP_CLS_DIR;
chdir $CLSFLD;
qx { jar xf $class_jar };
chdir $MYROOT;
# update jar
print "pack classes to jar file ...\n";
open FH, "< $class_list" or die "can't open $class_list: $!\n";
my $counter = 0;
while (<FH>) {
chomp;
my $orig_name = $_;
next if length $_ < 3;
if (/\.class/) {
print " pack path '$_' to jar ...\n";
unless (-f "$class_out_root/$_") {
print "ERROR! failed to find class '$orig_name'\n";
exit 1;
}
s/\$/\\\$/g unless $^O =~ /MSWin32/;
# unlink .class if exists
my $clspath = $_;
if ($clspath !~ /^(.+)\.class$/) {
print "ERROR! invalid class name '$clspath'\n";
exit 1;
}
my @clsout = glob("$TMP_CLS_DIR/$1" . "\$*.class");
unlink @clsout if (@clsout > 0);
# copy .class to dst dir
copy("$class_out_root/$clspath", "$TMP_CLS_DIR/$clspath");
$counter++;
} else {
print " pack class '$_' to jar ...\n";
s/\./\//g;
# unlink .class if exists
my @dst_clsout = glob("$TMP_CLS_DIR/$_" . "\$*.class");
unlink @dst_clsout if (@dst_clsout > 0);
my @clsout = glob("$class_out_root/$_" . "*.class");
if (@clsout == 0) {
print "ERROR! failed to find class '$orig_name' build-out classes.\n";
exit 1;
}
# copy .class to dst dir
foreach $x (@clsout) {
$x =~ s/\$/\\\$/g unless $^O =~ /MSWin32/;
$y = substr ($x, length($class_out_root));
copy("$x", $TMP_CLS_DIR.$y);
$counter++;
}
}
}
close FH;
# create .jar
print "building classes.jar...\n";
qx { jar cf $tmp_jar -C $CLSFLD . };
# dx jar
print "generating dex file...\n";
print "java -Xmx1024M -jar $DXJAR --dex --output=$dex_out $tmp_jar\n";
qx { java -Xmx1024M -jar "$DXJAR" --dex --output="$dex_out" $tmp_jar };
print "done! out dex is '$dex_out'.\n";
exit 0;
# // sub //
sub usage {
$x = basename $0;
print <<EOF;
usage: $x -r root_dir -c class_list -j classjar -o dex_out
options:
-r,--root the build-out root dir where the updated class is saved.
-c,--class the class list which will be updated into framework dex.
-j,--jar the class jar name under jar dir, such as "framework"
for "jar/framework.jar", etc, also support to use absolute
path to specify class jar, such as "/xxx/framework.jar".
-o,--output the output framework dex with updated classses.
NOTICE:
JRE "java, jar" must be in the search path! This script will invoke these tools.
EOF
}
2、services-update.bat
源码如下:
@echo off
set tool-path=D:\CPShare\framwork_deploy\update-jar-dex.v2.0
set class-root=D:\workspace\JavaDebug\bin
set class-file=services-classes.txt
set src-jar=services
set output=services.jar
set class=%tool-path%\%class-file%
@echo on
perl %tool-path%\update-jar-dex.pl -r %class-root% -c %class% -j %src-jar% -o %output%
pause
3、framework-update.bat
源码如下:
@echo off
set tool-path=D:\CPShare\framwork_deploy\update-jar-dex.v2.0
set class-root=D:\workspace\JavaDebug\bin
set class-file=framework-classes.txt
set src-jar=framework
set output=framework.jar
set class=%tool-path%\%class-file%
@echo on
perl %tool-path%\update-jar-dex.pl -r %class-root% -c %class% -j %src-jar% -o %output%
pause
4、services-classes.txt
这个文件里写入你要修改的class
如:
com.android.server.location.GpsLocationProvider
com.android.server.LocationManagerService
com.android.server.ServiceWatcher
5、framework-classes.txt
这个文件里写入你要修改的class
如:
android.util.NtpTrustedTime
6、新建一个java工程,将要修改的文件导入进去,并导入所需要的jar包
指定工程的目录:set class-root=D:\workspace\JavaDebug\bin