為了方便站在巨人臂膀上研讀源碼,特地將自己寫的源碼進行混淆之後與源碼進行比較。
使用混淆的方法在project.properties文件上加入
[plain
proguard.config=proguard.cfg
這一條代碼。關於如何反編譯源碼,請看之前的一篇博客如何反編繹APK文件。
一、代碼結構
1、源碼
2、未帶混淆機制代碼
3、混淆後的代碼
從圖中可以看出未帶混淆機制的代碼基本上與源碼的結構相同,同時加入了R文件和android.annotation包。而混淆之後的代碼刪除了TestCommon文件,因為沒有任何其他的文件使用到了這個文件當中的方法,因此使用混淆機制後其被刪除。
二、MyTabHost代碼分析
1、MyTabHost源碼
[java]
package com.yang.confusion;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TabHost;
public class MyTabHost extends TabHost {
public MyTabHost(Context context) {
super(context);
}
public MyTabHost(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TabSpec setIndicator(CharSequence label) {
return null;
}
private String str = null;
private static final int FLAG = 1;
//測試if
public void testIf() {
if (str == null) {
System.out.println("空");
}
}
/**
* 測試IfElse
*/
public void testIfElse() {
if (str == null) {
System.out.println("空");
} else {
System.out.println("不空");
}
}
public void testIfWhile() {
if (str == null) {
while (str == null) {
System.out.println("空");
}
}
}
public void testIfDoWhile() {
if (str == null) {
do {
System.out.println("空");
} while (str == null);
}
}
public void testFor() {
for (int i = 0; i < 10; i++) {
System.out.println("asdf");
}
}
public void testForIf() {
for (int i = 0; i < 10; i++) {
if (i == 1) {
System.out.println("asdf");
}
}
}
public void testWhile() {
while (str == null) {
System.out.println("空");
}
}
@SuppressWarnings("unused")
private void testSwitch(int key) {
switch (key) {
case FLAG:
break;
default:
break;
}
}
}TestActivity
2、未帶混淆機制MyTabHost代碼
[java]
package com.yang.confusion;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import java.io.PrintStream;
public class MyTabHost extends TabHost
{
private static final int FLAG = 1;
private String str = null;
public MyTabHost(Context paramContext)
{
super(paramContext);
}
public MyTabHost(Context paramContext, AttributeSet paramAttributeSet)
{
super(paramContext, paramAttributeSet);
}
private void testSwitch(int paramInt)
{
switch (paramInt)
{
case 1:
}
}
public TabHost.TabSpec setIndicator(CharSequence paramCharSequence)
{
return null;
}
public void testFor()
{
for (int i = 0; ; i++)
{
if (i >= 10)
return;
System.out.println("asdf");
}
}
public void testForIf()
{
for (int i = 0; ; i++)
{
if (i >= 10)
return;
if (i != 1)
continue;
System.out.println("asdf");
}
}
public void testIf()
{
if (this.str == null)
System.out.println("空");
}
public void testIfDoWhile()
{
if (this.str == null)
do
System.out.println("空");
while (this.str == null);
}
public void testIfElse()
{
if (this.str == null)
System.out.println("空");
while (true)
{
return;
System.out.println("不空");
}
}
public void testIfWhile()
{
if (this.str == null);
while (true)
{
if (this.str != null)
return;
System.out.println("空");
}
}
public void testWhile()
{
while (true)
{
if (this.str != null)
return;
System.out.println("空");
}
}
}
3、混淆後的MyTabHost代碼
[java]
package com.yang.confusion;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TabHost;
public class MyTabHost extends TabHost
{
private String a = null;
public MyTabHost(Context paramContext, AttributeSet paramAttributeSet)
{
super(paramContext, paramAttributeSet);
}
}
從中可以看出,只要源碼沒有進行混淆設置,還是可以讀懂的。沒有混淆機制的代碼,對源碼進行相應的改動,具體改動的目的不知道,但是還是可以看懂的。而對於混淆後的代碼,對源代碼進行了進一步的縮減,對源碼當中沒有使用到的方法全部刪除。【成都安卓培訓】
三、TestActivity代碼分析
1、TestActivity源碼
[java]
package com.yang.confusion;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
testIf();
testIfElse();
testIfWhile();
testIfDoWhile();
testFor();
testForIf();
testWhile();
testSwitch(2);
}
private String str = null;
private static final int FLAG = 1;
//測試if
public void testIf() {
if (str == null) {
System.out.println("空");
}
}
/**
* 測試IfElse
*/
public void testIfElse() {
if (str == null) {
System.out.println("空");
} else {
System.out.println("不空");
}
}
public void testIfWhile() {
if (str == null) {
while (str == null) {
System.out.println("空");
}
}
}
public void testIfDoWhile() {
if (str == null) {
do {
System.out.println("空");
} while (str == null);
}
}
public void testFor() {
for (int i = 0; i < 10; i++) {
System.out.println("asdf");
}
}
public void testForIf() {
for (int i = 0; i < 10; i++) {
if (i == 1) {
System.out.println("asdf");
}
}
}
public void testWhile() {
while (str == null) {
System.out.println("空");
}
}
private void testSwitch(int key) {
switch (key) {
case FLAG:
break;
default:
break;
}
}
}
2、未帶混淆機制的TestActivity代碼
[java]
package com.yang.confusion;
import android.app.Activity;
import android.os.Bundle;
import java.io.PrintStream;
public class TestActivity extends Activity
{
private static final int FLAG = 1;
private String str = null;
private void testSwitch(int paramInt)
{
switch (paramInt)
{
case 1:
}
}
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
testIf();
testIfElse();
testIfWhile();
testIfDoWhile();
testFor();
testForIf();
testWhile();
testSwitch(2);
}
public void testFor()
{
for (int i = 0; ; i++)
{
if (i >= 10)
return;
System.out.println("asdf");
}
}
public void testForIf()
{
for (int i = 0; ; i++)
{
if (i >= 10)
return;
if (i != 1)
continue;
System.out.println("asdf");
}
}
public void testIf()
{
if (this.str == null)
System.out.println("空");
}
public void testIfDoWhile()
{
if (this.str == null)
do
System.out.println("空");
while (this.str == null);
}
public void testIfElse()
{
if (this.str == null)
System.out.println("空");
while (true)
{
return;
System.out.println("不空");
}
}
public void testIfWhile()
{
if (this.str == null);
while (true)
{
if (this.str != null)
return;
System.out.println("空");
}
}
public void testWhile()
{
while (true)
{
if (this.str != null)
return;
System.out.println("空");
}
}
}
3、混淆後的TestActivity代碼 【成都安卓培訓】
[java]
package com.yang.confusion;
import android.app.Activity;
import android.os.Bundle;
import java.io.PrintStream;
public class TestActivity extends Activity
{
private String a = null;
protected void onCreate(Bundle paramBundle)
{
int i = 0;
super.onCreate(paramBundle);
if (this.a == null)
System.out.println("空");
label44: int j;
if (this.a == null)
{
System.out.println("空");
if (this.a == null)
if (this.a == null)
break label106;
if (this.a == null)
do
System.out.println("空");
while (this.a == null);
j = 0;
label75: if (j < 10)
break label117;
label81: if (i < 10)
break label131;
}
while (true)
{
if (this.a != null)
{
return;
System.out.println("不空");
break;
label106: System.out.println("空");
break label44;
label117: System.out.println("asdf");
j++;
break label75;
label131: if (i == 1)
System.out.println("asdf");
i++;
break label81;
}
System.out.println("空");
}
}
}
四、MainTabHostActivity代碼分析
1、MainTabHostActivity源碼
[java]
package com.yang.tabhost;
import android.app.TabActivity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;
/**
*
* @Title: MainTabHostActivity.java
* @Package com.yang.tabhost
* @Description: MainTabHostActivity
*
*/
public class MainTabHostActivity extends TabActivity {
private TabHost tabHost;
private TabWidget tabWidget;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// No Title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.main_layout);
makeTab();
}
private void makeTab() {
if (this.tabHost == null) {
tabHost = getTabHost();
tabWidget = getTabWidget();
tabHost.setup();
tabHost.bringToFront();
setupChild1();
setupChild2();
}
for (int i = 0; i < tabWidget.getChildCount(); i++) {
TextView tv = (TextView) tabWidget.getChildAt(i).findViewById(
android.R.id.title);
android.widget.RelativeLayout.LayoutParams tvp = new android.widget.RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
tvp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
tvp.addRule(RelativeLayout.CENTER_HORIZONTAL);
tv.setLayoutParams(tvp);
ImageView iv = (ImageView) tabWidget.getChildAt(i).findViewById(
android.R.id.icon);
android.widget.RelativeLayout.LayoutParams ivp = new android.widget.RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
ivp.addRule(RelativeLayout.CENTER_HORIZONTAL);
ivp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
iv.setLayoutParams(ivp);
// 得到每個tab
View vvv = tabWidget.getChildAt(i);
// 設置背景色為透明
vvv.setBackgroundColor(Color.TRANSPARENT);
// 設置字體顏色和大小
tv.setTextColor(this.getResources()
.getColorStateList(R.color.white));
tv.setTextSize(15);
}
}
private void setupChild2() {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.setClass(this, AnotherChildActivity.class);
String name = (String) this.getResources().getText(R.string.allimage);
tabHost.addTab(tabHost
.newTabSpec(name)
.setIndicator(name,
getResources().getDrawable(R.drawable.tab_selected))
.setContent(intent));
}
private void setupChild1() {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.setClass(this, ChildTabHostActivity.class);
String name = (String) this.getResources().getText(R.string.onepiece);
tabHost.addTab(tabHost
.newTabSpec(name)
.setIndicator(name,
getResources().getDrawable(R.drawable.tab_selected))
.setContent(intent));
}
}
2、未帶混淆機制的MainTabHostActivity代碼 【成都安卓培訓】
[java]
,
package com.yang.tabhost;
import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TabWidget;
import android.widget.TextView;
public class MainTabHostActivity extends TabActivity
{
private TabHost tabHost;
private TabWidget tabWidget;
private void makeTab()
{
if (this.tabHost == null)
{
this.tabHost = getTabHost();
this.tabWidget = getTabWidget();
this.tabHost.setup();
this.tabHost.bringToFront();
setupChild1();
setupChild2();
}
for (int i = 0; ; i++)
{
if (i >= this.tabWidget.getChildCount())
return;
TextView localTextView = (TextView)this.tabWidget.getChildAt(i).findViewById(16908310);
RelativeLayout.LayoutParams localLayoutParams1 = new RelativeLayout.LayoutParams(-2, -2);
localLayoutParams1.addRule(10);
localLayoutParams1.addRule(14);
localTextView.setLayoutParams(localLayoutParams1);
ImageView localImageView = (ImageView)this.tabWidget.getChildAt(i).findViewById(16908294);
RelativeLayout.LayoutParams localLayoutParams2 = new RelativeLayout.LayoutParams(-2, -2);
localLayoutParams2.addRule(14);
localLayoutParams2.addRule(12);
localImageView.setLayoutParams(localLayoutParams2);
this.tabWidget.getChildAt(i).setBackgroundColor(0);
localTextView.setTextColor(getResources().getColorStateList(2130968578));
localTextView.setTextSize(15.0F);
}
}
private void setupChild1()
{
Intent localIntent = new Intent();
localIntent.setAction("android.intent.action.MAIN");
localIntent.setClass(this, ChildTabHostActivity.class);
String str = (String)getResources().getText(2131034113);
this.tabHost.addTab(this.tabHost.newTabSpec(str).setIndicator(str, getResources().getDrawable(2130837512)).setContent(localIntent));
}
private void setupChild2()
{
Intent localIntent = new Intent();
localIntent.setAction("android.intent.action.MAIN");
localIntent.setClass(this, AnotherChildActivity.class);
String str = (String)getResources().getText(2131034114);
this.tabHost.addTab(this.tabHost.newTabSpec(str).setIndicator(str, getResources().getDrawable(2130837512)).setContent(localIntent));
}
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
requestWindowFeature(1);
requestWindowFeature(2);
setContentView(2130903041);
makeTab();
}
}
3、混淆後的MainTabHostActivity代碼
[java]
package com.yang.tabhost;
import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TabWidget;
import android.widget.TextView;
public class MainTabHostActivity extends TabActivity
{
private TabHost a;
private TabWidget b;
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
requestWindowFeature(1);
requestWindowFeature(2);
setContentView(2130903041);
if (this.a == null)
{
this.a = getTabHost();
this.b = getTabWidget();
this.a.setup();
this.a.bringToFront();
Intent localIntent1 = new Intent();
localIntent1.setAction("android.intent.action.MAIN");
localIntent1.setClass(this, ChildTabHostActivity.class);
String str1 = (String)getResources().getText(2131034113);
this.a.addTab(this.a.newTabSpec(str1).setIndicator(str1, getResources().getDrawable(2130837512)).setContent(localIntent1));
Intent localIntent2 = new Intent();
localIntent2.setAction("android.intent.action.MAIN");
localIntent2.setClass(this, AnotherChildActivity.class);
String str2 = (String)getResources().getText(2131034114);
this.a.addTab(this.a.newTabSpec(str2).setIndicator(str2, getResources().getDrawable(2130837512)).setContent(localIntent2));
}
for (int i = 0; ; i++)
{
if (i >= this.b.getChildCount())
return;
TextView localTextView = (TextView)this.b.getChildAt(i).findViewById(16908310);
RelativeLayout.LayoutParams localLayoutParams1 = new RelativeLayout.LayoutParams(-2, -2);
localLayoutParams1.addRule(10);
localLayoutParams1.addRule(14);
localTextView.setLayoutParams(localLayoutParams1);
ImageView localImageView = (ImageView)this.b.getChildAt(i).findViewById(16908294);
RelativeLayout.LayoutParams localLayoutParams2 = new RelativeLayout.LayoutParams(-2, -2);
localLayoutParams2.addRule(14);
localLayoutParams2.addRule(12);
localImageView.setLayoutParams(localLayoutParams2);
this.b.getChildAt(i).setBackgroundColor(0);
localTextView.setTextColor(getResources().getColorStateList(2130968578));
localTextView.setTextSize(15.0F);
}
}
}
從中可以看出,混淆後的代碼難以閱讀,但是可以從中找到規律,至於什麼規律,博主能力有限,看大家去找了……