Я создал простое приложение, приложение-счетчик, которое при нажатии кнопки увеличивает число на единицу и обновляет текстовое представление. Код можно увидеть ниже:
public class MainActivity extends Activity {
public static int count = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = (TextView) findViewById(R.id.count);
textView.setText(Integer.toString(count));
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
count++;
textView.setText(Integer.toString(count));
}
});
}
...
}
После декомпиляции того же приложения с dex2jar и jd-gui я получил следующий код:
public class MainActivity extends Activity {
public static int count = 0;
protected void onCreate(final Bundle paramBundle) {
super.onCreate(paramBundle);
setContentView(2130903040);
paramBundle = (TextView)findViewById(2131296257);
paramBundle.setText(Integer.toString(count));
((Button)findViewById(2131296256)).setOnClickListener(new View.OnClickListener() {
public void onClick(View paramAnonymousView) {
MainActivity.count += 1;
paramBundle.setText(Integer.toString(MainActivity.count));
}
});
}
...
}
В следующей строке:
paramBundle = (TextView)findViewById(2131296257);
paramBundle.setText(Integer.toString(count));
Как можно настроить систему textview на paramBundle? И почему это происходит? paramBundle имеет тип Bundle, а TextView не является подклассом Bundle, далее Bundle является окончательным в соответствии с декомпилированной версией. Что-то пошло не так при декомпиляции? Является ли информация из декомпилятора неправильной или почему мы получаем этот результат?
Edit:
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 3
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 17
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 18
const/high16 v2, 0x7f030000
invoke-virtual {p0, v2}, Lcom/example/rawa/helloworld/MainActivity;->setContentView(I)V
.line 20
const v2, 0x7f090001
invoke-virtual {p0, v2}, Lcom/example/rawa/helloworld/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v1
check-cast v1, Landroid/widget/TextView;
.line 21
.local v1, "textView":Landroid/widget/TextView;
sget v2, Lcom/example/rawa/helloworld/MainActivity;->count:I
invoke-static {v2}, Ljava/lang/Integer;->toString(I)Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
.line 22
const/high16 v2, 0x7f090000
invoke-virtual {p0, v2}, Lcom/example/rawa/helloworld/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/Button;
.line 23
.local v0, "button":Landroid/widget/Button;
new-instance v2, Lcom/example/rawa/helloworld/MainActivity$1;
invoke-direct {v2, p0, v1}, Lcom/example/rawa/helloworld/MainActivity$1;-><init>(Lcom/example/rawa/helloworld/MainActivity;Landroid/widget/TextView;)V
invoke-virtual {v0, v2}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 30
return-void
.end method
Я определенно не специалист по smali, только новичок. Но я также расшифровал приложение, используя apktool, и получил код smali выше. По моему мнению, сохраненное состояние (paramBundle) загружается в p1 (= v3) и используется в onCreate, и оно никоим образом не используется в строке 20 или 21. Для меня это указывает на ошибку декомпрессии? Имейте в виду, что apktool позволяет снова создавать приложение, и при декомпиляции данные не теряются.