【问题标题】:Unable to launch Activity in Release mode (with proguard-android-optimize configuration)无法在发布模式下启动 Activity(使用 proguard-android-optimize 配置)
【发布时间】:2016-09-14 10:35:58
【问题描述】:

我的应用程序中的此活动未在使用 proguard-android-optimize 配置的发布模式下启动。该活动在调试和发布配置下都能正常启动。由于错误仅发生在 proguard-android-optimize 配置中,因此我无法从 logcat 跟踪错误,因为它重命名了所有类。

这里是活动。 (检查函数 onCreateOptionsMenu() )

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import package.name.CardInfo;
import package.name.CardViewAdapter;
import package.name.DataStore;
import package.name.R;

public class SearchActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
    List<CardInfo> list;
    ArrayList<String> wrds;
    LinearLayoutManager ll;
    CardViewAdapter adapter;
    RecyclerView rv;
    List<CardInfo> all;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_search);
    Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(tb);
    list = new ArrayList<>();
    rv = (RecyclerView) findViewById(R.id.rv);
    new LoadData().execute();
}

class LoadData extends AsyncTask<Void, Void, Void> {
    List<CardInfo> a;
    ProgressDialog pd;
    DataStore ds;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        ds = new DataStore(SearchActivity.this);
        pd = new ProgressDialog(SearchActivity.this);
        pd.setMessage("Loading ..");
        pd.setIndeterminate(true);
        pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        pd.setCanceledOnTouchOutside(false);
        pd.show();
        a = new ArrayList<>();
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        pd.dismiss();
        all = a;
    }

    @Override
    protected Void doInBackground(Void... params) {
        ds.open();
        a = ds.getData();
        ds.close();
        Thread t = new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    Thread.sleep(2000);
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        };
        t.start();
        return null;
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // I believe problem is residing somewhere here in this function


    getMenuInflater().inflate(R.menu.search_activity_menu, menu);
    SearchView sv = (SearchView) menu.findItem(R.id.search_x).getActionView();
    ll = new LinearLayoutManager(getBaseContext());
    sv.onActionViewExpanded();
    sv.setOnQueryTextListener(this);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    return super.onOptionsItemSelected(item);
}

@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {
    if (newText.length() >= 1) {
        filter(newText);
        rv.setLayoutManager(ll);
        adapter = new CardViewAdapter(getSupportFragmentManager(), list);
        rv.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }
    return true;
}

void filter(String qry) {
    list.clear();
    wrds = getWords(qry);
    for (CardInfo i : all) {
        for (String query : wrds) {
            if (i.getAmount().toLowerCase().contains(query.toLowerCase()) ||
                    i.getAction().toLowerCase().contains(query.toLowerCase()) ||
                    i.getPurpose().toLowerCase().contains(query.toLowerCase()) ||
                    i.getDesc().toLowerCase().contains(query.toLowerCase()) ||
                    i.getYear().toLowerCase().contains(query.toLowerCase()) ||
                    i.getMonth().toLowerCase().contains(query.toLowerCase()) ||
                    i.getStore().toLowerCase().contains(query.toLowerCase()) ||
                    i.getDay().toLowerCase().contains(query.toLowerCase())

                    ) {
                if (!list.contains(i))
                    list.add(i);
            }
        }
    }
}


static ArrayList<String> getWords(String msg) {
    ArrayList<String> arr = new ArrayList<>();
    Pattern pattern = Pattern.compile("(\\S+)");
    Matcher matcher = pattern.matcher(msg);
    while (matcher.find()) {
        arr.add(matcher.group());
    }
    return arr;
}

}

这是我的 build.gradle 文件。

apply plugin: 'com.android.application'

android {
    signingConfigs {
        Pzy64Signing {
            keyAlias 'xxxx'
            keyPassword 'xxxxxxxx'
            storeFile file('/home/pz/bin/Android/keyStore/PzyKeystore.jks')
            storePassword 'xxxxxxxx'
        }
   }
compileSdkVersion 24
buildToolsVersion "24.0.2"

defaultConfig {
    applicationId "package.name"
    minSdkVersion 15
    targetSdkVersion 24
    versionCode 9
    versionName "9.0"
}
buildTypes {
    Pzt64Release {
        signingConfig signingConfigs.Pzy64Signing
        minifyEnabled true
        pseudoLocalesEnabled true
        proguardFile '/home/pz/bin/Android/android-sdk/tools/proguard/proguard-android-optimize.txt'
        zipAlignEnabled true
    }
}
productFlavors {
    Pzy64Config {
        proguardFile '/home/pz/bin/Android/android-sdk/tools/proguard/proguard-android-optimize.txt'
        signingConfig signingConfigs.Pzy64Signing
        versionCode 9
        versionName '9.0'
        minSdkVersion 15
        applicationId 'package.name'
        targetSdkVersion 24
    }
}
dexOptions {
    incremental true
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.android.support:design:24.2.0'
compile 'com.android.support:cardview-v7:24.2.0'
compile 'com.android.support:recyclerview-v7:24.2.0'
compile 'com.android.support:support-v4:24.2.0'
compile 'com.google.firebase:firebase-ads:9.2.1'
}
apply plugin: 'com.google.gms.google-services'

这里是日志猫

        FATAL EXCEPTION: main
    Process: package.name, PID: 14035
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.SearchView.a()' on a null object reference
    at pzy64.pocketmath.summary.SearchActivity.onCreateOptionsMenu(Unknown Source)
    at android.app.Activity.onCreatePanelMenu(Activity.java:2866)
    at android.support.v4.app.s.onCreatePanelMenu(Unknown Source)
    at android.support.v7.view.n.onCreatePanelMenu(Unknown Source)
    at android.support.v7.a.ai.onCreatePanelMenu(Unknown Source)
    at android.support.v7.view.n.onCreatePanelMenu(Unknown Source)
    at android.support.v7.a.bk.run(Unknown Source)
    at android.os.Handler.handleCallback(Handler.java:815)
    at android.os.Handler.dispatchMessage(Handler.java:104)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5550)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750)

【问题讨论】:

  • 为什么要从 proguardFiles 中删除 getDefaultProguardFile('proguard-android.txt')?您可以使用逗号分隔多个文件。在开头添加这个,然后添加你的
  • 那么我是否需要从 gradle 文件中删除 Pzt64Release 部分并添加 release 而不是 Pzy64Release 和逗号分隔的文件列表。
  • 这不是来自 proguard 的。该错误似乎来自proguard。只需编辑您的 proguardFiles。保留签名
  • 你的意思是 -keepattributes 签名
  • 不...我的意思是proguardFiles getDefaultProguardFile('proguard-android.txt'), '/home/pz/bin/Android/android-sdk/tools/proguard/proguard-android-optimize.txt'

标签: java android debugging android-activity build.gradle


【解决方案1】:

您需要使用默认的 proguard 文件来防止 Android 类(如活动、视图等)被您的 proguard 任务删除。

为此,Android 提供了一个名为 getDefaultProguardFile('proguard-android.txt') 的方法,您应该在所有项目中使用该方法,除非您想自己管理这些异常

如果使用proguardFiles 而不是proguardFile,则可以使用多个文件

proguardFiles getDefaultProguardFile('proguard-android.txt'),'/home/pz/bin‌​/Android/android-sdk‌​/tools/proguard/prog‌​uard-android-optimiz‌​e.txt', 'proguard-rules.pro'

还将这些行添加到 proguard-rules.pro 文件中

-keep class android.support.v7.widget.** { *; }
-keep interface android.support.v7.widget.** { *; }

【讨论】:

  • 还添加了 -keep class android.support.v7.** { ; } -keep interface android.support.v7.* { *; } 在 proguard-rules.pro 中
  • 有必要吗?
  • 我不确定默认文件是否保留它。但为了安全起见,最好保留它 :) 您可以在 Internet 上找到其他有更好记录的 proguard.pro 文件,例如这里 https://github.com/krschultz/android-proguard-snippets/tree/master/libraries
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多