启用 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 无法在设备中运行发布应用程序的主要内容,如果未能解决你的问题,请参考以下文章
使用 Joda Time 时无法生成启用 proguard 的签名 APK