启用 Proguard 无法在设备中运行发布应用程序

Posted

技术标签:

【中文标题】启用 Proguard 无法在设备中运行发布应用程序【英文标题】:Enabling Proguard not able to run release app in Device 【发布时间】:2015-02-20 12:24:01 【问题描述】:

我正在使用 Twitter api 1.1 版从各种渠道获取推文。从过去 3 天开始,我已经完成了启用 Proguard 以减少我的 apk 的所有过程。但它只在 DEVICE 中获取推文时由应用程序停止,而不是在 emulator 中。请帮忙

FragmentOne.java 执行期间

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ListFragment;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.gson.Gson;
import com.mypackage.facts.R;
import com.mypackage.twitter.Authenticated;
import com.mypackage.twitter.SingleListItem;
import com.mypackage.twitter.Tweet;
import com.mypackage.twitter.Twitter;
import com.mypackage.twitter.TwitterUser;

@SuppressLint("NewApi")
public class FragmentOne extends ListFragment  
    public boolean net;
    ImageView ivIcon;
    TextView tvItemName;
    final static String LOG_TAG = "rnc";
     ListView listview;
       String product;
       AdView adView;
    //   private InterstitialAd interstitial;
    public FragmentOne() 

    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 

        View view = inflater.inflate(R.layout.twit_list, container,
                false);

        downloadTweets();


        return view;

    

         @Override
            public void onListItemClick(ListView l, View v, int position, long id) 
                Log.i("FragmentList2", "Item clicked: " + id);

                Object selectedValue = this.getListAdapter().getItem(position);
                product = selectedValue.toString();

           //     System.out.println("lota "+product);

                Intent intent = new Intent(FragmentOne.this.getActivity(), SingleListItem.class);
                intent.putExtra("product", product);
            //    Toast.makeText(getActivity(), item, Toast.LENGTH_LONG).show();
              startActivity(intent);
            


    public void downloadTweets() 
        TwitterUser o = new TwitterUser();
        String m = o.getValue();

         System.out.println("Kida   "+m);


    //   listview = this.getListView();



         String ScreenName =m;

        ConnectivityManager connMgr = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.isConnected()) 
            new DownloadTwitterTask().execute(ScreenName);
         else 
            Log.v(LOG_TAG, "No network connection available.");
        
    



    // Uses an AsyncTask to download a Twitter user's timeline
        private class DownloadTwitterTask extends AsyncTask<String, Void, String> 
            final static String CONSUMER_KEY = "3GCPNkJ9cZesXIBDaMyYHDkqU";
            final static String CONSUMER_SECRET = "sPxxPRfXGonaIcWT6r5GbWwU4cSZWW0tmXv2HD5VX3RDYkCoDG";
            final static String TwitterTokenURL = "https://api.twitter.com/oauth2/token";
            final static String TwitterStreamURL = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=";


            private ProgressDialog progressDialog;  
            @Override
            // can use UI thread here
            protected void onPreExecute() 
            //this.progressDialog = ProgressDialog.show(Boys.this, ""," Look whose back !! Ok Let me see what i have for you ");  
                try
                progressDialog = new ProgressDialog(FragmentOne.this.getActivity(),AlertDialog.THEME_HOLO_DARK);
                progressDialog.setIndeterminate(true);
                progressDialog.setIndeterminateDrawable(getResources().getDrawable(R.drawable.loader_2));
                progressDialog.setMessage("Have Some Patience Please...");
                progressDialog.show();
            //  progressDialog.setCancelable(false);
            //  progressDialog.setCanceledOnTouchOutside(false);
                
                catch(Exception e)
                
                    this.progressDialog.dismiss();
                    Toast.makeText(getActivity().getApplicationContext(),e.toString(), Toast.LENGTH_LONG).show();

                
            

            @Override
            protected String doInBackground(String... screenNames) 
                String result = null;

                if (screenNames.length > 0) 
                    result = getTwitterStream(screenNames[0]);
                
                return result;
            

            // onPostExecute convert the JSON results into a Twitter object (which is an Array list of tweets
            @Override
            protected void onPostExecute(String result) 
                Twitter twits = jsonToTwitter(result);

                // lets write the results to the console as well
                for (Tweet tweet : twits) 
                    Log.i(LOG_TAG, tweet.getText());
                

                System.out.println("Kamina "+ twits);

                // send the tweets to the adapter for rendering

                    ArrayAdapter<Tweet> adapter = new ArrayAdapter<Tweet>(getActivity().getBaseContext(),R.layout.customgrid,R.id.texts, twits);
                    setListAdapter(adapter);

                     showAd();
                this.progressDialog.dismiss();
            

            // converts a string of JSON data into a Twitter object
            private Twitter jsonToTwitter(String result) 
                Twitter twits = null;
                if (result != null && result.length() > 0) 
                    try 
                        Gson gson = new Gson();
                        twits = gson.fromJson(result, Twitter.class);
                     catch (IllegalStateException ex) 
                        // just eat the exception
                    
                
                return twits;
            

            // convert a JSON authentication object into an Authenticated object
            private Authenticated jsonToAuthenticated(String rawAuthorization) 
                Authenticated auth = null;
                if (rawAuthorization != null && rawAuthorization.length() > 0) 
                    try 
                        Gson gson = new Gson();
                        auth = gson.fromJson(rawAuthorization, Authenticated.class);
                     catch (IllegalStateException ex) 
                        // just eat the exception
                    
                
                return auth;
            

            private String getResponseBody(HttpRequestBase request) 
                StringBuilder sb = new StringBuilder();
                try 

                    DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
                    HttpResponse response = httpClient.execute(request);
                    int statusCode = response.getStatusLine().getStatusCode();
                    String reason = response.getStatusLine().getReasonPhrase();

                    if (statusCode == 200) 

                        HttpEntity entity = response.getEntity();
                        InputStream inputStream = entity.getContent();

                        BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                        String line = null;
                        while ((line = bReader.readLine()) != null) 
                            sb.append(line);
                        
                     else 
                        sb.append(reason);
                    
                 catch (UnsupportedEncodingException ex) 
                 catch (ClientProtocolException ex1) 
                 catch (IOException ex2) 
                
                return sb.toString();
            

            private String getTwitterStream(String screenName) 
                String results = null;

                // Step 1: Encode consumer key and secret
                try 
                    // URL encode the consumer key and secret
                    String urlApiKey = URLEncoder.encode(CONSUMER_KEY, "UTF-8");
                    String urlApiSecret = URLEncoder.encode(CONSUMER_SECRET, "UTF-8");

                    // Concatenate the encoded consumer key, a colon character, and the
                    // encoded consumer secret
                    String combined = urlApiKey + ":" + urlApiSecret;

                    // Base64 encode the string
                    String base64Encoded = Base64.encodeToString(combined.getBytes(), Base64.NO_WRAP);

                    // Step 2: Obtain a bearer token
                    HttpPost httpPost = new HttpPost(TwitterTokenURL);
                    httpPost.setHeader("Authorization", "Basic " + base64Encoded);
                    httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
                    httpPost.setEntity(new StringEntity("grant_type=client_credentials"));
                    String rawAuthorization = getResponseBody(httpPost);
                    Authenticated auth = jsonToAuthenticated(rawAuthorization);

                    // Applications should verify that the value associated with the
                    // token_type key of the returned object is bearer
                    if (auth != null && auth.token_type.equals("bearer")) 

                        // Step 3: Authenticate API requests with bearer token
                        HttpGet httpGet = new HttpGet(TwitterStreamURL + screenName+"&count=10");

                        // construct a normal HTTPS request and include an Authorization
                        // header with the value of Bearer <>
                        httpGet.setHeader("Authorization", "Bearer " + auth.access_token);
                        httpGet.setHeader("Content-Type", "application/json");
                        // update the results with the body of the response
                        results = getResponseBody(httpGet);
                    
                 catch (UnsupportedEncodingException ex) 
                 catch (IllegalStateException ex1) 
                
                return results;
            
        


        void showAd()
          



                // Prepare the Interstitial Ad
            //  interstitial = new InterstitialAd(getActivity());
                // Insert the Ad Unit ID
            //  interstitial.setAdUnitId("ca-app-pub-2123194616447553/4834655305");

                //Locate the Banner Ad in activity_main.xml
                AdView adView = (AdView) this.getView().findViewById(R.id.adViews);

                // Request for Ads
                AdRequest adRequest = new AdRequest.Builder()

                // Add a test device to show Test Ads
                 .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
                 .addTestDevice("Ku")
                        .build();

                // Load ads into Banner Ads
                adView.loadAd(adRequest);


                    // Load ads into Interstitial Ads
            //  interstitial.loadAd(adRequest);

                // Prepare an Interstitial Ad Listener
            /*  interstitial.setAdListener(new AdListener() 
                    public void onAdLoaded() 
                        // Call displayInterstitial() function
                        displayInterstitial();
                    
                );*/

          

        /*   public void displayInterstitial() 
                // If Ads are loaded, show Interstitial else show nothing.
                if (interstitial.isLoaded()) 
                    interstitial.show();
                
            */



程序文件

project.properties

# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=$sdk.dir/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-19
android.library.reference.1=..\\appcompat_v7
android.library.reference.2=../google-play-services_lib

proguard-project.txt

# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in $sdk.dir/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the javascript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview 
#   public *;
#

【问题讨论】:

任何崩溃?如果是这样,请发布 logcat。并显示你的 proguard txt 文件 当我在设备上运行时不行,然后它崩溃了。没有来自 logcat 的报告 【参考方案1】:

终于解决了

https://***.com/a/16312437/3682964

现在一切正常!感谢这位用户。

【讨论】:

以上是关于启用 Proguard 无法在设备中运行发布应用程序的主要内容,如果未能解决你的问题,请参考以下文章

启用 Proguard 后无法实例化片段

使用 Joda Time 时无法生成启用 proguard 的签名 APK

启用 proguard,我的构建版本应用程序不会再次安装

无法使用 ProGuard 实例化 AndroidPlatform 类

Win32 API 函数以编程方式启用/禁用设备

无法在我的 android 应用程序中使 proguard 工作