├── AndroidProguardPlugin.zip ├── src └── com │ └── zhw │ └── proguard │ ├── bean │ ├── BaseBean.java │ └── ResultBean.java │ ├── AndroidProGuardAction.java │ ├── AndroidComponent.java │ └── net │ └── HttpUtils.java ├── resources └── META-INF │ └── plugin.xml ├── AndroidProguardPlugin.iml └── README.md /AndroidProguardPlugin.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhonghanwen/AndroidProguardPlugin/HEAD/AndroidProguardPlugin.zip -------------------------------------------------------------------------------- /src/com/zhw/proguard/bean/BaseBean.java: -------------------------------------------------------------------------------- 1 | package com.zhw.proguard.bean; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by zhonghanwen on 2016/6/7. 8 | */ 9 | public class BaseBean implements Serializable { 10 | public List results; 11 | } 12 | -------------------------------------------------------------------------------- /src/com/zhw/proguard/bean/ResultBean.java: -------------------------------------------------------------------------------- 1 | package com.zhw.proguard.bean; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by zhonghanwen on 2016/6/7. 7 | */ 8 | public class ResultBean implements Serializable { 9 | public String content; 10 | public int id; 11 | public String name; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/com/zhw/proguard/AndroidProGuardAction.java: -------------------------------------------------------------------------------- 1 | package com.zhw.proguard; 2 | 3 | import com.intellij.openapi.actionSystem.AnAction; 4 | import com.intellij.openapi.actionSystem.AnActionEvent; 5 | import com.intellij.openapi.application.Application; 6 | import com.intellij.openapi.application.ApplicationManager; 7 | 8 | /** 9 | * Created by zhonghanwen on 2016/6/7. 10 | */ 11 | public class AndroidProGuardAction extends AnAction { 12 | 13 | @Override 14 | public void actionPerformed(AnActionEvent e) { 15 | // TODO: insert action logic here 16 | Application application = ApplicationManager.getApplication(); 17 | AndroidComponent androidComponent = application.getComponent(AndroidComponent.class); 18 | androidComponent.sayHello(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | com.zhw.tgnet.android.AndroidProGuard 3 | AndroidProGuard Pro 4 | 1.4 5 | Beijing,LongDong 6 | 7 | 9 | 10 | ]]> 11 | 12 | 14 | 2、update the plugin name.
15 | ]]> 16 |
17 | 18 | 19 | 20 | 21 | 23 | 24 | com.intellij.modules.java 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | com.zhw.proguard.AndroidComponent 43 | 44 | 45 |
-------------------------------------------------------------------------------- /AndroidProguardPlugin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AndroidProguardPlugin 2 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-AndroidProguardPlugin-green.svg?style=true)](https://android-arsenal.com/details/1/3721) 3 | 4 | OneKey Android Studio generate proguard codes 5 | 6 | 一键生成项目混淆代码插件,值得你安装~ 7 | 8 | # Screenshot 9 | ![](http://7xrnko.com1.z0.glb.clouddn.com/androidproguard1.gif) 10 | 11 | # Library List 12 | 目前插件的后台已集成了如下图的第三方开源库的代码混淆以及基本的代码混淆,还在努力地添加中,也欢迎大家通过new issue提交列表中没有的第三方开源库混淆代码。(你认为微不足道的事情,也许可以帮到别人的大忙~) 13 | 14 | ![](http://7xrnko.com1.z0.glb.clouddn.com/library_list.png) 15 | 16 | 17 | # How to use 18 | 1. 目前可以在Android Studio -> Plugins -> Browse Repsitiories进行搜索"AndroidProGurad Pro"点击下载安装并重启。或者直接点击下载AndroidProGuard插件并安装重启。[download](https://raw.githubusercontent.com/zhonghanwen/AndroidProguardPlugin/master/AndroidProguardPlugin.zip) 19 | 2. 在菜单栏的Edit下拉菜单中选择AndroidProGuard选项。 20 | 3. 如果弹出成功对话框,就可以按Ctrl+V粘贴到项目的proguard-rules.pro文件。 21 | 4. 根据proguard-rules.pro报错的提示进行修改成。 22 | 5. 将项目app下gradle文件将minifyEnabled修改成true就可以测试混淆效果。 (你可以使用AndroidKiller反编译看一下效果,AndroidKiller的使用可以参考我写的这篇文章[here](http://www.cnblogs.com/common1140/p/5198460.html)) 23 | 24 | # **Note** 25 | 1. 实际的项目通常会有多个的Module,对于多个Module的代码混淆网上资料比较少,经过我实验得出:**对于多个Module的项目,在应用的Module(即app)下的proguard-rules.pro文件添加混淆代码以及在Gradle里minifyEnabled开启即可**。 26 | 27 | 2. 如果项目在编译的时候报warn信息,那么你可以使用-keep或者-dontwarn保留warn的类。 28 | 29 | # End 30 | 我知道项目的代码混淆一般通常混淆一次就可以了,很多人认为这个插件的意义不太,但是我可以告诉你我也是这么想的,可是我也无办法阻止我的行动~哈哈~~ 31 | 32 | # Update 33 | 34 | ![](http://7xrnko.com1.z0.glb.clouddn.com/androidproguard_three_part.png) 35 | 36 | update 20171029 37 | * 新增fresco/更新Gilde/新增科大讯飞. 38 | 39 | # License 40 | 41 | Copyright 2016 zhonghanwen 42 | 43 | Licensed under the Apache License, Version 2.0 (the "License"); 44 | you may not use this file except in compliance with the License. 45 | You may obtain a copy of the License at 46 | 47 | http://www.apache.org/licenses/LICENSE-2.0 48 | 49 | Unless required by applicable law or agreed to in writing, software 50 | distributed under the License is distributed on an "AS IS" BASIS, 51 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 52 | See the License for the specific language governing permissions and 53 | limitations under the License. 54 | -------------------------------------------------------------------------------- /src/com/zhw/proguard/AndroidComponent.java: -------------------------------------------------------------------------------- 1 | package com.zhw.proguard; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.intellij.openapi.components.ApplicationComponent; 5 | import com.intellij.openapi.options.Configurable; 6 | import com.intellij.openapi.options.ConfigurationException; 7 | import com.intellij.openapi.ui.Messages; 8 | import com.zhw.proguard.bean.BaseBean; 9 | import com.zhw.proguard.bean.ResultBean; 10 | import com.zhy.http.okhttp.OkHttpUtils; 11 | import com.zhy.http.okhttp.callback.StringCallback; 12 | import com.zhy.http.okhttp.https.HttpsUtils; 13 | import okhttp3.Call; 14 | import okhttp3.OkHttpClient; 15 | import org.jetbrains.annotations.Nls; 16 | import org.jetbrains.annotations.NotNull; 17 | import org.jetbrains.annotations.Nullable; 18 | 19 | import javax.swing.*; 20 | import java.awt.*; 21 | import java.awt.datatransfer.StringSelection; 22 | 23 | /** 24 | * Created by zhonghanwen on 2016/6/7. 25 | */ 26 | public class AndroidComponent implements ApplicationComponent, Configurable { 27 | 28 | private String content = ""; 29 | private boolean isLoading = true; 30 | 31 | 32 | public AndroidComponent() { 33 | HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null); 34 | OkHttpClient okHttpClient = new OkHttpClient.Builder() 35 | .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager) 36 | //其他配置 37 | .build(); 38 | OkHttpUtils.initClient(okHttpClient); 39 | } 40 | 41 | @Override 42 | public void initComponent() { 43 | // TODO: insert component initialization logic here 44 | } 45 | 46 | @Override 47 | public void disposeComponent() { 48 | // TODO: insert component disposal logic here 49 | } 50 | 51 | @Override 52 | @NotNull 53 | public String getComponentName() { 54 | return "AndroidComponent"; 55 | } 56 | 57 | 58 | public void sayHello() { 59 | content = ""; 60 | isLoading = false; 61 | // Show dialog with message 62 | String baseUrl = "https://api.bmob.cn/1/classes/proguard"; 63 | OkHttpUtils 64 | .get() 65 | .url(baseUrl) 66 | .addHeader("X-Bmob-Application-Id", "8032a3407adfe5b02689f9cc3962fffe") 67 | .addHeader("X-Bmob-REST-API-Key", "043c532e6050fae1056acc1127741458") 68 | .addHeader("Content-Type","application/json") 69 | .build() 70 | .execute(new StringCallback() 71 | { 72 | @Override 73 | public void onError(Call call, Exception e, int i) { 74 | isLoading = false; 75 | } 76 | 77 | @Override 78 | public void onResponse(String s, int code) { 79 | if (s != null){ 80 | BaseBean baseBean = JSON.parseObject(s, BaseBean.class); 81 | if (baseBean.results != null){ 82 | for (ResultBean bean : baseBean.results){ 83 | content += bean.content + "\n"; 84 | } 85 | } 86 | // System.out.println(content); 87 | StringSelection stsel = new StringSelection(content); 88 | Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stsel, stsel); 89 | isLoading = false; 90 | } 91 | } 92 | 93 | }); 94 | 95 | while (true){ 96 | if (!isLoading){ 97 | showSucceedDialog(); 98 | break; 99 | } 100 | } 101 | } 102 | 103 | private void showSucceedDialog() { 104 | Messages.showMessageDialog( 105 | "Android Proguard Codes Generate Succeed~ " + 106 | "\n Please paste codes(Ctrl+V) in proguard-rules.pro!", 107 | "AndroidProGuard", 108 | Messages.getInformationIcon() 109 | 110 | ); 111 | } 112 | 113 | @Nls 114 | @Override 115 | public String getDisplayName() { 116 | return null; 117 | } 118 | 119 | @Nullable 120 | @Override 121 | public String getHelpTopic() { 122 | return null; 123 | } 124 | 125 | @Nullable 126 | @Override 127 | public JComponent createComponent() { 128 | return null; 129 | } 130 | 131 | @Override 132 | public boolean isModified() { 133 | return false; 134 | } 135 | 136 | @Override 137 | public void apply() throws ConfigurationException { 138 | 139 | } 140 | 141 | @Override 142 | public void reset() { 143 | 144 | } 145 | 146 | @Override 147 | public void disposeUIResources() { 148 | 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/com/zhw/proguard/net/HttpUtils.java: -------------------------------------------------------------------------------- 1 | package com.zhw.proguard.net; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.InputStreamReader; 8 | import java.io.PrintWriter; 9 | import java.net.HttpURLConnection; 10 | import java.net.URL; 11 | 12 | //Http请求的工具类 13 | public class HttpUtils 14 | { 15 | 16 | private static final int TIMEOUT_IN_MILLIONS = 5000; 17 | 18 | public interface CallBack 19 | { 20 | void onRequestComplete(String result); 21 | } 22 | 23 | 24 | /** 25 | * 异步的Get请求 26 | * 27 | * @param urlStr 28 | * @param callBack 29 | */ 30 | public static void doGetAsyn(final String urlStr, final CallBack callBack) 31 | { 32 | new Thread() 33 | { 34 | public void run() 35 | { 36 | try 37 | { 38 | String result = doGet(urlStr); 39 | if (callBack != null) 40 | { 41 | callBack.onRequestComplete(result); 42 | } 43 | } catch (Exception e) 44 | { 45 | e.printStackTrace(); 46 | } 47 | 48 | }; 49 | }.start(); 50 | } 51 | 52 | /** 53 | * 异步的Post请求 54 | * @param urlStr 55 | * @param params 56 | * @param callBack 57 | * @throws Exception 58 | */ 59 | public static void doPostAsyn(final String urlStr, final String params, 60 | final CallBack callBack) throws Exception 61 | { 62 | new Thread() 63 | { 64 | public void run() 65 | { 66 | try 67 | { 68 | String result = doPost(urlStr, params); 69 | if (callBack != null) 70 | { 71 | callBack.onRequestComplete(result); 72 | } 73 | } catch (Exception e) 74 | { 75 | e.printStackTrace(); 76 | } 77 | 78 | }; 79 | }.start(); 80 | 81 | } 82 | 83 | /** 84 | * Get请求,获得返回数据 85 | * 86 | * @param urlStr 87 | * @return 88 | * @throws Exception 89 | */ 90 | public static String doGet(String urlStr) 91 | { 92 | URL url = null; 93 | HttpURLConnection conn = null; 94 | InputStream is = null; 95 | ByteArrayOutputStream baos = null; 96 | try 97 | { 98 | url = new URL(urlStr); 99 | conn = (HttpURLConnection) url.openConnection(); 100 | conn.setReadTimeout(TIMEOUT_IN_MILLIONS); 101 | conn.setConnectTimeout(TIMEOUT_IN_MILLIONS); 102 | conn.setRequestMethod("GET"); 103 | conn.setRequestProperty("accept", "*/*"); 104 | conn.setRequestProperty("X-Bmob-REST-API-Key","8032a3407adfe5b02689f9cc3962fffe"); 105 | conn.setRequestProperty("X-Bmob-REST-API-Key","043c532e6050fae1056acc1127741458"); 106 | conn.setRequestProperty("connection", "Keep-Alive"); 107 | conn.setRequestProperty("Content-Type", "application/json"); 108 | if (conn.getResponseCode() == 200) 109 | { 110 | is = conn.getInputStream(); 111 | baos = new ByteArrayOutputStream(); 112 | int len = -1; 113 | byte[] buf = new byte[128]; 114 | 115 | while ((len = is.read(buf)) != -1) 116 | { 117 | baos.write(buf, 0, len); 118 | } 119 | baos.flush(); 120 | return baos.toString(); 121 | } else 122 | { 123 | throw new RuntimeException(" responseCode is not 200 ... "); 124 | } 125 | 126 | } catch (Exception e) 127 | { 128 | e.printStackTrace(); 129 | } finally 130 | { 131 | try 132 | { 133 | if (is != null) 134 | is.close(); 135 | } catch (IOException e) 136 | { 137 | } 138 | try 139 | { 140 | if (baos != null) 141 | baos.close(); 142 | } catch (IOException e) 143 | { 144 | } 145 | conn.disconnect(); 146 | } 147 | 148 | return null ; 149 | 150 | } 151 | 152 | /** 153 | * 向指定 URL 发送POST方法的请求 154 | * 155 | * @param url 156 | * 发送请求的 URL 157 | * @param param 158 | * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 159 | * @return 所代表远程资源的响应结果 160 | * @throws Exception 161 | */ 162 | public static String doPost(String url, String param) 163 | { 164 | PrintWriter out = null; 165 | BufferedReader in = null; 166 | String result = ""; 167 | try 168 | { 169 | URL realUrl = new URL(url); 170 | // 打开和URL之间的连接 171 | HttpURLConnection conn = (HttpURLConnection) realUrl 172 | .openConnection(); 173 | // 设置通用的请求属性 174 | conn.setRequestProperty("accept", "*/*"); 175 | conn.setRequestProperty("connection", "Keep-Alive"); 176 | conn.setRequestMethod("POST"); 177 | conn.setRequestProperty("Content-Type", 178 | "application/x-www-form-urlencoded"); 179 | conn.setRequestProperty("charset", "utf-8"); 180 | conn.setUseCaches(false); 181 | // 发送POST请求必须设置如下两行 182 | conn.setDoOutput(true); 183 | conn.setDoInput(true); 184 | conn.setReadTimeout(TIMEOUT_IN_MILLIONS); 185 | conn.setConnectTimeout(TIMEOUT_IN_MILLIONS); 186 | 187 | if (param != null && !param.trim().equals("")) 188 | { 189 | // 获取URLConnection对象对应的输出流 190 | out = new PrintWriter(conn.getOutputStream()); 191 | // 发送请求参数 192 | out.print(param); 193 | // flush输出流的缓冲 194 | out.flush(); 195 | } 196 | // 定义BufferedReader输入流来读取URL的响应 197 | in = new BufferedReader( 198 | new InputStreamReader(conn.getInputStream())); 199 | String line; 200 | while ((line = in.readLine()) != null) 201 | { 202 | result += line; 203 | } 204 | } catch (Exception e) 205 | { 206 | e.printStackTrace(); 207 | } 208 | // 使用finally块来关闭输出流、输入流 209 | finally 210 | { 211 | try 212 | { 213 | if (out != null) 214 | { 215 | out.close(); 216 | } 217 | if (in != null) 218 | { 219 | in.close(); 220 | } 221 | } catch (IOException ex) 222 | { 223 | ex.printStackTrace(); 224 | } 225 | } 226 | return result; 227 | } 228 | } --------------------------------------------------------------------------------