From f796cdfc60fbb4dde34d7d0ebd0a241f5545cb51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B0=B8=E5=8D=8E?= Date: Fri, 9 Jun 2017 13:31:17 +0800 Subject: [PATCH 01/13] add dex inject plugin --- .idea/gradle.xml | 1 + .idea/misc.xml | 2 +- .idea/modules.xml | 1 + buildSrc/.gitignore | 1 + buildSrc/build.gradle | 12 + .../davy/commons/plugin/InjectPlugin.groovy | 18 ++ .../commons/plugin/InjectTransform.groovy | 92 ++++++ .../org/davy/commons/plugin/MyInject.groovy | 60 ++++ .../commons/plugin/OnlyCopyTransform.groovy | 92 ++++++ .../main/java/org/davy/commons/IOUtils.java | 8 +- samples/build.gradle | 3 + samples/src/main/AndroidManifest.xml | 4 + samples/src/main/assets/data.xml | 284 ++++++++++++++++++ .../davy/commons/samples/MainActivity.java | 117 +++++++- .../java/org/davy/commons/samples/Test.java | 13 + .../java/org/davy/commons/samples/Utils.java | 33 ++ settings.gradle | 2 +- 17 files changed, 739 insertions(+), 4 deletions(-) create mode 100644 buildSrc/.gitignore create mode 100644 buildSrc/build.gradle create mode 100644 buildsrc/src/main/groovy/org/davy/commons/plugin/InjectPlugin.groovy create mode 100644 buildsrc/src/main/groovy/org/davy/commons/plugin/InjectTransform.groovy create mode 100644 buildsrc/src/main/groovy/org/davy/commons/plugin/MyInject.groovy create mode 100644 buildsrc/src/main/groovy/org/davy/commons/plugin/OnlyCopyTransform.groovy create mode 100644 samples/src/main/assets/data.xml create mode 100644 samples/src/main/java/org/davy/commons/samples/Test.java create mode 100644 samples/src/main/java/org/davy/commons/samples/Utils.java diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 1765860..613c50c 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -8,6 +8,7 @@ - - - - - - - - - - - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 64383c4..02f1ec8 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,8 +3,8 @@ - + diff --git a/build.gradle b/build.gradle index b78a0b8..95d0e7d 100644 --- a/build.gradle +++ b/build.gradle @@ -3,9 +3,10 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.1' + classpath 'com.android.tools.build:gradle:3.1.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0f1949a..7e06bb7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Jun 08 13:10:58 CST 2017 +#Thu Jun 07 22:54:29 CST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/library/build.gradle b/library/build.gradle index 6e8d203..501d903 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -2,7 +2,6 @@ apply plugin: 'com.android.library' android { compileSdkVersion 25 - buildToolsVersion "25.0.3" defaultConfig { minSdkVersion 19 diff --git a/library/src/androidTest/java/org/davy/commons/ExampleInstrumentedTest.java b/library/src/androidTest/java/org/davy/commons/ExampleInstrumentedTest.java deleted file mode 100644 index f1a4785..0000000 --- a/library/src/androidTest/java/org/davy/commons/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.davy.commons; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumentation test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("org.davy.commons.test", appContext.getPackageName()); - } -} diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml index ef3fc20..81812c0 100644 --- a/library/src/main/AndroidManifest.xml +++ b/library/src/main/AndroidManifest.xml @@ -1,12 +1,7 @@ - package="org.davy.commons"> - - - - - - - + + + diff --git a/library/src/main/java/org/davy/commons/FileExistsException.java b/library/src/main/java/org/davy/commons/FileExistsException.java deleted file mode 100644 index e02c1e5..0000000 --- a/library/src/main/java/org/davy/commons/FileExistsException.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.davy.commons; - -import java.io.File; -import java.io.IOException; - -/** - * Indicates that a file already exists. - */ -public class FileExistsException extends IOException { - - private static final long serialVersionUID = 1L; - - public FileExistsException() { - super(); - } - - public FileExistsException(final String message) { - super(message); - } - - public FileExistsException(final File file) { - super("File " + file + " exists"); - } - -} diff --git a/library/src/main/java/org/davy/commons/NetworkUtil.java b/library/src/main/java/org/davy/commons/NetworkUtil.java deleted file mode 100644 index 28a287d..0000000 --- a/library/src/main/java/org/davy/commons/NetworkUtil.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.davy.commons; - -import android.content.ContentResolver; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.DhcpInfo; -import android.net.NetworkInfo; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.provider.Settings; -import android.support.annotation.NonNull; -import android.support.annotation.WorkerThread; -import android.text.TextUtils; -import android.text.format.Formatter; -import android.util.Log; - -import java.io.IOException; - -/** - * Created by davy on 2017/5/23. - */ - -public class NetworkUtil { - - private static final String TAG = "NetworkUtil"; - - private static final String ETHERNET_USE_STATIC_IP = "ethernet_use_static_ip"; - private static final String ETHERNET_STATIC_IP = "ethernet_static_ip"; - private static final String ETHERNET_STATIC_GATEWAY = "ethernet_static_gateway"; - private static final String ETHERNET_STATIC_NETMASK = "ethernet_static_netmask"; - private static final String ETHERNET_STATIC_DNS1 = "ethernet_static_dns1"; - private static final String ETHERNET_STATIC_DNS2 = "ethernet_static_dns2"; - private static final String ETH0 = "eth0"; - - public static boolean isConnected(Context context) { - ConnectivityManager connManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = connManager.getActiveNetworkInfo(); - if (networkInfo != null) { - return networkInfo.isAvailable(); - } - return false; - } - - public static boolean isEthernetConnected(Context context) { - ConnectivityManager connManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET); - if (networkInfo != null) { - return networkInfo.isAvailable(); - } - return false; - } - - @WorkerThread - public static boolean pingToken(@NonNull String urlNoHttpOrIp) { - Runtime runtime = Runtime.getRuntime(); - - try { - Process e = runtime.exec("/system/bin/ping -c 1 " + urlNoHttpOrIp); - int exitValue = e.waitFor(); - return exitValue == 0; - } catch (InterruptedException | IOException var4) { - //ignore - return false; - } - } - - public static String getCurrentIp(Context context) { - String ip = ""; - StringBuilder stringBuilder = new StringBuilder(); - ConnectivityManager connectivityManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); - - if (networkInfo != null) { - if (networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) { - if (Settings.System.getInt(context.getContentResolver(), ETHERNET_USE_STATIC_IP, 0) == 1) { - return getStaticEthInfo(context); - } else { - return getEthInfoFromDhcp(context); - } - } else if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { - WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); - DhcpInfo dhcpInfo = wifiManager.getDhcpInfo(); - if (dhcpInfo != null) { - stringBuilder.append(dhcpInfo.ipAddress).append(" ").append(Formatter.formatIpAddress(dhcpInfo.ipAddress)).append(" \n"); - stringBuilder.append(dhcpInfo.netmask).append(" ").append(Formatter.formatIpAddress(dhcpInfo.netmask)).append(" \n"); - stringBuilder.append(dhcpInfo.gateway).append(" ").append(Formatter.formatIpAddress(dhcpInfo.gateway)).append(" \n"); - stringBuilder.append(dhcpInfo.ipAddress & dhcpInfo.netmask).append(" ").append(Formatter.formatIpAddress(dhcpInfo.ipAddress & dhcpInfo.netmask)).append(" \n"); - stringBuilder.append(dhcpInfo.dns1).append(" ").append(Formatter.formatIpAddress(dhcpInfo.dns1)).append(" \n"); - stringBuilder.append(dhcpInfo.dns2).append(" ").append(Formatter.formatIpAddress(dhcpInfo.dns2)).append(" \n"); - ip = Formatter.formatIpAddress(dhcpInfo.ipAddress); - } else { - WifiInfo wifiInfo = wifiManager.getConnectionInfo(); - if (wifiInfo != null) { - ip = Formatter.formatIpAddress(wifiInfo.getIpAddress()); - } - } - } else { - stringBuilder.append("未知连接类型" + networkInfo.getTypeName() + "\n\n"); - } - } else { - stringBuilder.append("无网络连接" + "\n\n"); - } - Log.d("TAG", stringBuilder.toString()); - return ip; - } - - public static String getStaticEthInfo(Context context) { - StringBuilder stringBuilder = new StringBuilder(); - ContentResolver contentResolver = context.getContentResolver(); - stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_USE_STATIC_IP)).append(" \n"); - stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_IP)).append(" \n"); - stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_GATEWAY)).append(" \n"); - stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_NETMASK)).append(" \n"); - stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_DNS1)).append(" \n"); - stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_DNS2)).append(" \n"); - Log.d("TAG", stringBuilder.toString()); - return Settings.System.getString(contentResolver, ETHERNET_STATIC_IP); - } - - public static String getEthInfoFromDhcp(Context context) { - String dhcpIp = ""; - StringBuilder stringBuilder = new StringBuilder(); - dhcpIp = SystemPropertiesHelper.get("dhcp." + ETH0 + ".ipaddress"); - stringBuilder.append("ipaddr:").append(dhcpIp).append(" \n"); - stringBuilder.append("gateway:").append(SystemPropertiesHelper.get("dhcp." + ETH0 + ".gateway")).append(" \n"); - stringBuilder.append("mask:").append(SystemPropertiesHelper.get("dhcp." + ETH0 + ".mask")).append(" \n"); - stringBuilder.append("dns1:").append(SystemPropertiesHelper.get("dhcp." + ETH0 + ".dns1")).append(" \n"); - stringBuilder.append("dns2:").append(SystemPropertiesHelper.get("dhcp." + ETH0 + ".dns2")).append(" \n"); - Log.d("TAG", stringBuilder.toString()); - return dhcpIp; - } -} diff --git a/library/src/main/java/org/davy/commons/SystemPropertiesHelper.java b/library/src/main/java/org/davy/commons/SystemPropertiesHelper.java deleted file mode 100644 index bdc4738..0000000 --- a/library/src/main/java/org/davy/commons/SystemPropertiesHelper.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.davy.commons; - -import java.lang.reflect.Method; - -/** - * 反射调用SystemProperties - * Created by davy on 2017/6/7. - */ - -public class SystemPropertiesHelper { - private static Class mClassType = null; - private static Method mGetMethod = null; - private static Method mGetIntMethod = null; - - private static void init() { - try { - if (mClassType == null) { - mClassType = Class.forName("android.os.SystemProperties"); - mGetMethod = mClassType.getDeclaredMethod("get", String.class); - mGetIntMethod = mClassType.getDeclaredMethod("getInt", String.class, int.class); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static String get(String key) { - init(); - String value = null; - try { - value = (String) mGetMethod.invoke(mClassType, key); - } catch (Exception e) { - e.printStackTrace(); - } - return value; - } -} diff --git a/library/src/main/java/org/davy/utils/AppUtils.java b/library/src/main/java/org/davy/utils/AppUtils.java new file mode 100644 index 0000000..46bfce4 --- /dev/null +++ b/library/src/main/java/org/davy/utils/AppUtils.java @@ -0,0 +1,244 @@ +package org.davy.utils; + +import android.app.ActivityManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; + +import java.util.List; + +import javax.security.auth.x500.X500Principal; + +/** + * @author: wlj + * @Date: 2017-03-28 + * @email: wanglijundev@gmail.com + * @desc: App 相关信息,包括版本名称、版本号、包名等等 + */ + +public class AppUtils { + private final static X500Principal DEBUG_DN = new X500Principal( + "CN=Android Debug,O=Android,C=US"); + + /** + * Get version name + * + * @param context + * @return + */ + public static String getVersionName(Context context) { + PackageInfo info; + try { + info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + return info.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return ""; + } + + /** + * Get version code + * + * @param context + * @return + */ + public static int getVersionCode(Context context) { + PackageInfo info; + try { + info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + return info.versionCode; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return 0; + } + + /** + * Get package name + * + * @param context + * @return + */ + public static String getPackageName(Context context) { + return context.getPackageName(); + } + + /** + * Get icon + * + * @param context + * @return + */ + public static Drawable getIcon(Context context) { + return getAppIcon(context, getPackageName(context)); + } + + /** + * Get app icon + * + * @param context + * @param packageName + * @return + */ + public static Drawable getAppIcon(Context context, String packageName) { + try { + PackageManager pm = context.getPackageManager(); + ApplicationInfo info = pm.getApplicationInfo(packageName, 0); + return info.loadIcon(pm); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Get app version name + * + * @param context + * @param packageName + * @return + */ + public static String getAppVersionName(Context context, String packageName) { + try { + PackageManager pm = context.getPackageManager(); + PackageInfo packageInfo = pm.getPackageInfo(packageName, 0); + return packageInfo.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Get app version code + * + * @param context + * @param packageName + * @return + */ + public static int getAppVersionCode(Context context, String packageName) { + try { + PackageManager pm = context.getPackageManager(); + PackageInfo packageInfo = pm.getPackageInfo(packageName, 0); + return packageInfo.versionCode; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return -1; + } + + /** + * Get app name + * + * @param context + * @param packageName + * @return + */ + public static String getAppName(Context context, String packageName) { + try { + PackageManager pm = context.getPackageManager(); + ApplicationInfo info = pm.getApplicationInfo(packageName, 0); + return info.loadLabel(pm).toString(); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Get app permission + * + * @param context + * @param packageName + * @return + */ + public static String[] getAppPermission(Context context, String packageName) { + try { + PackageManager pm = context.getPackageManager(); + PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); + return packageInfo.requestedPermissions; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Get app signature + * + * @param context + * @param packageName + * @return + */ + public static String getAppSignature(Context context, String packageName) { + try { + PackageManager pm = context.getPackageManager(); + PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); + return packageInfo.signatures[0].toCharsString(); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Judge whether an app is dubuggable + * + * @param context + * @return + */ + public static boolean isApkDebuggable(Context context) { + try { + ApplicationInfo info = context.getApplicationInfo(); + return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + } catch (Exception e) { + + } + return false; + } + + /** + * Judge whether an app is dubuggable by package name + * + * @param context + * @param packageName + * @return + */ + public static boolean isApkDebugable(Context context, String packageName) { + try { + PackageInfo pkginfo = context.getPackageManager().getPackageInfo( + packageName, PackageManager.GET_ACTIVITIES); + if (pkginfo != null) { + ApplicationInfo info = pkginfo.applicationInfo; + return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + } + } catch (Exception e) { + } + return false; + } + + /** + * Judge whether an app is in background + * + * @param context + * @return + */ + public static boolean isAppInBackground(Context context) { + ActivityManager am = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + List taskList = am.getRunningTasks(1); + if (taskList != null && !taskList.isEmpty()) { + ComponentName topActivity = taskList.get(0).topActivity; + if (topActivity != null + && !topActivity.getPackageName().equals( + context.getPackageName())) { + return true; + } + } + return false; + } +} diff --git a/library/src/main/java/org/davy/utils/AssetsUtils.java b/library/src/main/java/org/davy/utils/AssetsUtils.java new file mode 100644 index 0000000..577a842 --- /dev/null +++ b/library/src/main/java/org/davy/utils/AssetsUtils.java @@ -0,0 +1,93 @@ +package org.davy.utils; + +import android.content.Context; +import android.content.res.AssetManager; +import android.support.annotation.NonNull; +import android.support.annotation.WorkerThread; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * @desc: Assets操作 + */ + +public class AssetsUtils { + private static final String ENCODING = "UTF-8"; + + /** + * 从assets获取文件 + * + * @param context + * @param fileName + * @return + * @throws IOException + */ + public static InputStream getFileFromAssets(@NonNull Context context, String fileName) throws IOException { + AssetManager am = context.getAssets(); + return am.open(fileName); + } + + /** + * 从assets获取文本文件 + * + * @param context + * @param fileName + * @return + */ + @WorkerThread + public static String asset2String(@NonNull Context context, String fileName) { + + StringBuilder stringBuilder = new StringBuilder(); + + InputStream inputStream = null; + BufferedInputStream bufferedInputStream = null; + InputStreamReader inputStreamReader = null; + BufferedReader bufReader = null; + + try { + inputStream = getFileFromAssets(context, fileName); + bufferedInputStream = new BufferedInputStream(inputStream); + inputStreamReader = new InputStreamReader(bufferedInputStream); + bufReader = new BufferedReader(inputStreamReader); + + String line; + StringBuilder result = new StringBuilder(); + while ((line = bufReader.readLine()) != null) { + result.append(line); + } + } catch (IOException e) { + // ignore + } finally { + IOUtils.closeQuietly(inputStream, bufferedInputStream, inputStreamReader, bufReader); + } + return stringBuilder.toString(); + } + + @WorkerThread + public static void copyAssetsFile(@NonNull Context context, @NonNull final String assetsFileName, @NonNull final String destFilePath) throws IOException { + + InputStream inputStream = null; + FileOutputStream fileOutputStream = null; + try { + + File desFile = new File(destFilePath); + if (desFile.exists()) { + return; + } + + fileOutputStream = new FileOutputStream(desFile); + inputStream = getFileFromAssets(context, assetsFileName); + IOUtils.copy(inputStream, fileOutputStream); + } catch (Exception e) { + throw e; + } finally { + IOUtils.closeQuietly(inputStream, fileOutputStream); + } + } +} diff --git a/library/src/main/java/org/davy/utils/Base64Utils.java b/library/src/main/java/org/davy/utils/Base64Utils.java new file mode 100644 index 0000000..f7edac5 --- /dev/null +++ b/library/src/main/java/org/davy/utils/Base64Utils.java @@ -0,0 +1,49 @@ +package org.davy.utils; + +import android.util.Base64; + +/** + * @desc: bese64的转换 + */ + +public class Base64Utils { + /** + * base64编码 + * + * @param input + * @return + */ + public static byte[] encode(byte[] input) { + return Base64.encode(input, Base64.DEFAULT); + } + + /** + * base64编码 + * + * @param s + * @return + */ + public static String encode(String s) { + return Base64.encodeToString(s.getBytes(), Base64.DEFAULT); + } + + /** + * base64解码 + * + * @param input + * @return + */ + public static byte[] decode(byte[] input) { + return Base64.decode(input, Base64.DEFAULT); + } + + /** + * base64解码 + * + * @param s + * @return + */ + public static String decode(String s) { + return new String(Base64.decode(s, Base64.DEFAULT)); + } +} diff --git a/library/src/main/java/org/davy/utils/BitmapUtils.java b/library/src/main/java/org/davy/utils/BitmapUtils.java new file mode 100644 index 0000000..46228df --- /dev/null +++ b/library/src/main/java/org/davy/utils/BitmapUtils.java @@ -0,0 +1,73 @@ +package org.davy.utils; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.view.View; + +public class BitmapUtils { + + public static final int UNSPECIFIED = 0; + + public static Bitmap convertViewToBitmap(View view, int width, int height) { + view.measure(View.MeasureSpec.makeMeasureSpec(width, (width == UNSPECIFIED) ? View.MeasureSpec.UNSPECIFIED : + View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(height, (height == UNSPECIFIED) ? View.MeasureSpec.UNSPECIFIED : + View.MeasureSpec.EXACTLY)); + view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); + Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888); + view.draw(new Canvas(bitmap)); + return bitmap; + } + + /** + * Convert view to bitmap + * + * @param view + * @return + */ + public static Bitmap convertViewToBitmap(View view) { + return convertViewToBitmap(view, UNSPECIFIED, UNSPECIFIED); + } + + public static Bitmap convertGreyImg(Bitmap img) { + int width = img.getWidth(); // 获取位图的宽 + int height = img.getHeight(); // 获取位图的高 + + int[] pixels = new int[width * height]; // 通过位图的大小创建像素点数组 + + img.getPixels(pixels, 0, width, 0, 0, width, height); + int alpha = 0xFF << 24; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + int grey = pixels[width * i + j]; + + int red = ((grey & 0x00FF0000) >> 16); + int green = ((grey & 0x0000FF00) >> 8); + int blue = (grey & 0x000000FF); + + grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11); + grey = alpha | (grey << 16) | (grey << 8) | grey; + pixels[width * i + j] = grey; + } + } + Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + result.setPixels(pixels, 0, width, 0, 0, width, height); + return result; + } + + public static Bitmap reverseHorizontal(Bitmap bitmap) { + Matrix matrix = new Matrix(); + matrix.preScale(-1, 1); + return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), + bitmap.getHeight(), matrix, false); + } + + public static Bitmap reverseVertical(Bitmap bitmap) { + Matrix matrix = new Matrix(); + matrix.preScale(1, -1); + return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), + bitmap.getHeight(), matrix, false); + } + +} diff --git a/library/src/main/java/org/davy/commons/ByteUtil.java b/library/src/main/java/org/davy/utils/ByteUtil.java similarity index 81% rename from library/src/main/java/org/davy/commons/ByteUtil.java rename to library/src/main/java/org/davy/utils/ByteUtil.java index 66a8251..54d99a6 100644 --- a/library/src/main/java/org/davy/commons/ByteUtil.java +++ b/library/src/main/java/org/davy/utils/ByteUtil.java @@ -1,16 +1,18 @@ -package org.davy.commons; +package org.davy.utils; import java.util.Locale; public class ByteUtil { + private final static byte[] EMPTY_BYTES = new byte[]{}; private final static char[] mChars = "0123456789ABCDEF".toCharArray(); public static String bytes2HexStr(byte[] bytes, int start, int length) { + if (bytes == null || bytes.length == 0 || start > bytes.length || start + length > bytes.length) { return ""; } - int position = 1; + StringBuilder builder = new StringBuilder(); for (int i = start; i < start + length; i++) { builder.append(mChars[(bytes[i] & 0xFF) >> 4]); @@ -21,23 +23,19 @@ public static String bytes2HexStr(byte[] bytes, int start, int length) { } public static String bytes2HexStr(byte[] bytes) { + if (bytes == null || bytes.length == 0) { return ""; } - StringBuilder builder = new StringBuilder(); - for (byte b : bytes) { - builder.append(mChars[(b & 0xFF) >> 4]); - builder.append(mChars[b & 0x0F]); - builder.append(" "); - } - return builder.toString(); + + return bytes2HexStr(bytes, 0, bytes.length); } private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } - public static byte[] hexString2Bytes(String hexString) { + public static byte[] str2Bytes(String hexString) { if (hexString == null || hexString.equals("")) { return EMPTY_BYTES; } diff --git a/library/src/main/java/org/davy/utils/CollectionUtils.java b/library/src/main/java/org/davy/utils/CollectionUtils.java new file mode 100644 index 0000000..2c440dc --- /dev/null +++ b/library/src/main/java/org/davy/utils/CollectionUtils.java @@ -0,0 +1,84 @@ +package org.davy.utils; + +import android.text.TextUtils; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 集合工具类 + */ + +public class CollectionUtils { + private static final String DELIMITER = ","; + + /** + * 判断集合是否为空 + * + * @param c + * @param + * @return + */ + public static boolean isEmpty(Collection c) { + return (c == null || c.isEmpty()); + } + + /** + * 判断集合是否不为空 + * + * @param c + * @param + * @return + */ + public static boolean isNotEmpty(Collection c) { + return !isEmpty(c); + } + /** + * Join collection to string, separator is {@link #DELIMITER} + * + * @param tokens + * @return + */ + public static String join(Iterable tokens) { + return tokens == null ? "" : TextUtils.join(DELIMITER, tokens); + } + + /** + * 将数组转为list + * + * @param array + * @param + * @return + */ + public static List asList(T... array) { + return Arrays.asList(array); + } + + /** + * 将数组转为set集合 + * + * @param array + * @param + * @return + */ + public static Set asSet(T... array) { + return new HashSet(asList(array)); + } + + /** + * 集合转为数组 + * + * @param c + * @return + */ + public static Object[] asArray(Collection c) { + if (!isEmpty(c)) { + return c.toArray(); + } + return null; + } + +} diff --git a/library/src/main/java/org/davy/utils/DisplayUtils.java b/library/src/main/java/org/davy/utils/DisplayUtils.java new file mode 100644 index 0000000..fee4a99 --- /dev/null +++ b/library/src/main/java/org/davy/utils/DisplayUtils.java @@ -0,0 +1,98 @@ +package org.davy.utils; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Rect; +import android.support.annotation.NonNull; +import android.util.DisplayMetrics; + +public class DisplayUtils { + /** + * Get screen width, in pixels + * + * @param context + * @return + */ + public static int getScreenWidth(Context context) { + DisplayMetrics dm = context.getResources().getDisplayMetrics(); + return dm.widthPixels; + } + + /** + * Get screen height, in pixels + * + * @param context + * @return + */ + public static int getScreenHeight(Context context) { + DisplayMetrics dm = context.getResources().getDisplayMetrics(); + return dm.heightPixels; + } + + /** + * Get screen density, the logical density of the display + * + * @param context + * @return + */ + public static float getScreenDensity(Context context) { + DisplayMetrics dm = context.getResources().getDisplayMetrics(); + return dm.density; + } + + /** + * Get screen density dpi, the screen density expressed as dots-per-inch + * + * @param context + * @return + */ + public static int getScreenDensityDPI(Context context) { + DisplayMetrics dm = context.getResources().getDisplayMetrics(); + return dm.densityDpi; + } + + /** + * Get statusbar height + * + * @param activity + * @return + */ + public static int getStatusBarHeight(@NonNull Activity activity) { + Rect rect = new Rect(); + activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); + int statusBarHeight = rect.top; + if (0 == statusBarHeight) { + Class localClass; + try { + localClass = Class.forName("com.android.internal.R$dimen"); + Object localObject = localClass.newInstance(); + int id = Integer.parseInt(localClass.getField("status_bar_height").get(localObject).toString()); + statusBarHeight = activity.getResources().getDimensionPixelSize(id); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (NumberFormatException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + } + return statusBarHeight; + } + + public static int dip2px(Context context, float dipValue){ + final float scale = context.getResources().getDisplayMetrics().density; + return (int)(dipValue * scale + 0.5f); + } + public static int px2dip(Context context, float pxValue){ + final float scale = context.getResources().getDisplayMetrics().density; + return (int)(pxValue / scale + 0.5f); + } +} diff --git a/samples/src/main/java/org/davy/commons/samples/Utils.java b/library/src/main/java/org/davy/utils/DumpUtils.java similarity index 76% rename from samples/src/main/java/org/davy/commons/samples/Utils.java rename to library/src/main/java/org/davy/utils/DumpUtils.java index c27ce94..dc3f6a8 100644 --- a/samples/src/main/java/org/davy/commons/samples/Utils.java +++ b/library/src/main/java/org/davy/utils/DumpUtils.java @@ -1,14 +1,8 @@ -package org.davy.commons.samples; +package org.davy.utils; -/** - * Created by davy on 2017/6/9. - */ +public class DumpUtils { -public class Utils { - - public Utils() { - Class ss = this.getClass(); - System.out.println(ss.getPackage().getName()); + private DumpUtils() { } public static int getLineNumber( ){ @@ -30,4 +24,4 @@ public static String getClassName( ){ StackTraceElement[] stackTrace = new Throwable().getStackTrace(); return stackTrace[1].getClassName(); } -} +} \ No newline at end of file diff --git a/library/src/main/java/org/davy/commons/FileUtils.java b/library/src/main/java/org/davy/utils/FileUtils.java similarity index 99% rename from library/src/main/java/org/davy/commons/FileUtils.java rename to library/src/main/java/org/davy/utils/FileUtils.java index 8e15281..4b5fbdd 100644 --- a/library/src/main/java/org/davy/commons/FileUtils.java +++ b/library/src/main/java/org/davy/utils/FileUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.davy.commons; +package org.davy.utils; import java.io.File; import java.io.FileFilter; diff --git a/library/src/main/java/org/davy/commons/IOUtils.java b/library/src/main/java/org/davy/utils/IOUtils.java similarity index 98% rename from library/src/main/java/org/davy/commons/IOUtils.java rename to library/src/main/java/org/davy/utils/IOUtils.java index 3e5b73e..dd58d0e 100644 --- a/library/src/main/java/org/davy/commons/IOUtils.java +++ b/library/src/main/java/org/davy/utils/IOUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.davy.commons; +package org.davy.utils; import java.io.Closeable; import java.io.IOException; diff --git a/library/src/main/java/org/davy/utils/MD5Utils.java b/library/src/main/java/org/davy/utils/MD5Utils.java new file mode 100644 index 0000000..b44e9d1 --- /dev/null +++ b/library/src/main/java/org/davy/utils/MD5Utils.java @@ -0,0 +1,40 @@ +package org.davy.utils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * + * MD5工具类 + */ + +public class MD5Utils { + + private MD5Utils() { + } + + public static String encode(String s) { + try { + MessageDigest digest = MessageDigest.getInstance("MD5"); + digest.update(s.getBytes()); + byte messageDigest[] = digest.digest(); + return ByteUtil.bytes2HexStr(messageDigest); + } catch (NoSuchAlgorithmException e) { + //ignore + } + return ""; + } + + public static String encode(byte[] bytes) { + try { + MessageDigest digest = MessageDigest.getInstance("MD5"); + digest.update(bytes); + byte messageDigest[] = digest.digest(); + return ByteUtil.bytes2HexStr(messageDigest); + } catch (NoSuchAlgorithmException e) { + //ignore + } + return ""; + } + +} diff --git a/library/src/main/java/org/davy/utils/NetworkUtil.java b/library/src/main/java/org/davy/utils/NetworkUtil.java new file mode 100644 index 0000000..e974dbc --- /dev/null +++ b/library/src/main/java/org/davy/utils/NetworkUtil.java @@ -0,0 +1,58 @@ +package org.davy.utils; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.support.annotation.NonNull; +import android.support.annotation.WorkerThread; + +import java.io.IOException; + +/** + * Created by davy on 2017/5/23. + */ + +public class NetworkUtil { + + private static final String TAG = "NetworkUtil"; + + private static final String ETHERNET_USE_STATIC_IP = "ethernet_use_static_ip"; + private static final String ETHERNET_STATIC_IP = "ethernet_static_ip"; + private static final String ETHERNET_STATIC_GATEWAY = "ethernet_static_gateway"; + private static final String ETHERNET_STATIC_NETMASK = "ethernet_static_netmask"; + private static final String ETHERNET_STATIC_DNS1 = "ethernet_static_dns1"; + private static final String ETHERNET_STATIC_DNS2 = "ethernet_static_dns2"; + private static final String ETH0 = "eth0"; + + public static boolean isConnected(Context context) { + ConnectivityManager connManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo networkInfo = connManager.getActiveNetworkInfo(); + if (networkInfo != null) { + return networkInfo.isAvailable(); + } + return false; + } + + public static boolean isEthernetConnected(Context context) { + ConnectivityManager connManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET); + if (networkInfo != null) { + return networkInfo.isAvailable(); + } + return false; + } + + @WorkerThread + public static boolean pingToken(@NonNull String urlNoHttpOrIp) { + Runtime runtime = Runtime.getRuntime(); + + try { + Process e = runtime.exec("/system/bin/ping -c 1 " + urlNoHttpOrIp); + int exitValue = e.waitFor(); + return exitValue == 0; + } catch (InterruptedException | IOException var4) { + //ignore + return false; + } + } +} diff --git a/library/src/main/java/org/davy/utils/NumberUtils.java b/library/src/main/java/org/davy/utils/NumberUtils.java new file mode 100644 index 0000000..480a072 --- /dev/null +++ b/library/src/main/java/org/davy/utils/NumberUtils.java @@ -0,0 +1,26 @@ +package org.davy.utils; + +import java.text.DecimalFormat; + +/** + * @author wlj + * @date 2017/3/29 + * @email wanglijundev@gmail.com + * @packagename wanglijun.vip.androidutils.utils + * @desc: 数字格式化操作类 + */ + +public class NumberUtils { + + private static final DecimalFormat oneDec = new DecimalFormat("##0.0"); + private static final DecimalFormat twoDec = new DecimalFormat("##0.00"); + + public static String formatOneDecimal(float number) { + return oneDec.format(number); + } + + public static String formatTwoDecimal(float number) { + DecimalFormat twoDec = new DecimalFormat("##0.00"); + return twoDec.format(number); + } +} diff --git a/library/src/main/java/org/davy/utils/ObjectUtils.java b/library/src/main/java/org/davy/utils/ObjectUtils.java new file mode 100644 index 0000000..7d59ab0 --- /dev/null +++ b/library/src/main/java/org/davy/utils/ObjectUtils.java @@ -0,0 +1,8 @@ +package org.davy.utils; + +public class ObjectUtils { + + public static boolean equals(Object a, Object b) { + return a != null && a.equals(b); + } +} diff --git a/library/src/main/java/org/davy/utils/PackageUtils.java b/library/src/main/java/org/davy/utils/PackageUtils.java new file mode 100644 index 0000000..5eba5df --- /dev/null +++ b/library/src/main/java/org/davy/utils/PackageUtils.java @@ -0,0 +1,141 @@ +package org.davy.utils; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.support.annotation.NonNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author wlj + * @date 2017/3/29 + * @email wanglijundev@gmail.com + * @packagename wanglijun.vip.androidutils.utils + * @desc: 包的相关操作 + */ + +public class PackageUtils { + + public static boolean checkPermission(@NonNull Context context, String permName, String pkgName) { + PackageManager pm = context.getPackageManager(); + return (PackageManager.PERMISSION_GRANTED == pm.checkPermission(permName, pkgName)); + } + + public static boolean checkPermission(@NonNull Context context, String permName) { + int perm = context.checkCallingOrSelfPermission(permName); + return perm == PackageManager.PERMISSION_GRANTED; + } + + public static boolean install(@NonNull Context context, String filePath) { + File file = new File(filePath); + if (!file.exists() || !file.isFile() || file.length() <= 0) { + return false; + } + + Intent i = new Intent(Intent.ACTION_VIEW); + i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive"); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(i); + return true; + } + + public static boolean uninstall(Context context, String packageName) { + if (packageName == null || packageName.length() == 0) { + return false; + } + + Intent i = new Intent(Intent.ACTION_DELETE, Uri.parse(new StringBuilder(32).append("package:") + .append(packageName).toString())); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(i); + return true; + } + + public static boolean isSystemApplication(Context context) { + if (context == null) { + return false; + } + return isSystemApplication(context, context.getPackageName()); + } + + public static boolean isSystemApplication(Context context, String packageName) { + if (context == null) { + return false; + } + return isSystemApplication(context.getPackageManager(), packageName); + } + + public static boolean isSystemApplication(PackageManager packageManager, String packageName) { + if (packageManager == null || packageName == null || packageName.length() == 0) { + return false; + } + try { + ApplicationInfo app = packageManager.getApplicationInfo(packageName, 0); + return (app != null && (app.flags & ApplicationInfo.FLAG_SYSTEM) > 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return false; + } + + /** + * 获取所有安装包信息 + */ + public static List getInstalledPackageInfos(Context context) { + return context.getPackageManager().getInstalledPackages(0); + } + + public static List getThirdPartyAllApps(Context context) { + List apps = new ArrayList(); + PackageManager packageManager = context.getPackageManager(); + List packageInfos = packageManager.getInstalledPackages(0); + for (int i = 0; i < packageInfos.size(); i++) { + PackageInfo pak = packageInfos.get(i); + if ((pak.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != ApplicationInfo.FLAG_SYSTEM) { + apps.add(pak); + } + } + return apps; + } + + public static void startApp(Context context, String packageName) { + PackageInfo packageinfo = null; + try { + packageinfo = context.getPackageManager().getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageinfo == null) { + return; + } + + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); + resolveIntent.setPackage(packageinfo.packageName); + + List resolveinfoList = context.getPackageManager() + .queryIntentActivities(resolveIntent, 0); + + ResolveInfo resolveinfo = resolveinfoList.iterator().next(); + if (resolveinfo != null) { + String pkgName = resolveinfo.activityInfo.packageName; + String className = resolveinfo.activityInfo.name; + + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + + ComponentName cn = new ComponentName(pkgName, className); + intent.setComponent(cn); + context.startActivity(intent); + } + } +} diff --git a/library/src/main/java/org/davy/utils/RandomUtils.java b/library/src/main/java/org/davy/utils/RandomUtils.java new file mode 100644 index 0000000..c25a46f --- /dev/null +++ b/library/src/main/java/org/davy/utils/RandomUtils.java @@ -0,0 +1,64 @@ +package org.davy.utils; + +import java.util.Random; + +/** + * 随机数操作类 + */ + +public class RandomUtils { + /** + * Returns a pseudo-random uniformly distributed {@code int}. + * 返回伪随机均匀分布 + * + * @return + */ + public static int randomInt() { + Random random = new Random(); + return random.nextInt(); + } + + public static int randomInt(int n) { + Random random = new Random(); + return random.nextInt(n); + } + + public static int randomInt(int min, int max) { + Random random = new Random(); + return random.nextInt(max) % (max - min + 1) + min; + } + + + public static float randomFloat() { + Random random = new Random(); + return random.nextFloat(); + } + + public static double randomDouble() { + Random random = new Random(); + return random.nextDouble(); + } + + + public static long randomLong() { + Random random = new Random(); + return random.nextLong(); + } + + + public static boolean randomBoolean() { + Random random = new Random(); + return random.nextBoolean(); + } + + + public static double randomGaussian() { + Random random = new Random(); + return random.nextGaussian(); + } + + public static void randomBytes(byte[] buf) { + Random random = new Random(); + random.nextBytes(buf); + } +} diff --git a/library/src/main/java/org/davy/commons/RegUtil.java b/library/src/main/java/org/davy/utils/RegexUtils.java similarity index 50% rename from library/src/main/java/org/davy/commons/RegUtil.java rename to library/src/main/java/org/davy/utils/RegexUtils.java index ac01fac..280d8a0 100644 --- a/library/src/main/java/org/davy/commons/RegUtil.java +++ b/library/src/main/java/org/davy/utils/RegexUtils.java @@ -1,6 +1,4 @@ -package org.davy.commons; - -import android.text.TextUtils; +package org.davy.utils; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -9,7 +7,28 @@ * Created by davy on 2017/5/18. */ -public class RegUtil { +public class RegexUtils { + + public static boolean isEmail(String email) { + Pattern pattern = Pattern + .compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)" + + "+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$"); + Matcher matcher = pattern.matcher(email); + return matcher.matches(); + } + + public static boolean isMobileNumber(String number) { + String expr = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"; + return number.matches(expr); + } + + public static boolean isUrl(String url) { + String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; + Pattern patt = Pattern.compile(regex); + Matcher matcher = patt.matcher(url); + return matcher.matches(); + } + public static boolean isIp(String str) { if (str == null || str.trim().equals("")) { return false; diff --git a/library/src/main/java/org/davy/utils/SHA1Utils.java b/library/src/main/java/org/davy/utils/SHA1Utils.java new file mode 100644 index 0000000..e21e32e --- /dev/null +++ b/library/src/main/java/org/davy/utils/SHA1Utils.java @@ -0,0 +1,36 @@ +package org.davy.utils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * SHA1 操作类 + */ + +public class SHA1Utils { + + public static String encode(String s) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.update(s.getBytes()); + byte messageDigest[] = digest.digest(); + return ByteUtil.bytes2HexStr(messageDigest); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return ""; + } + + public static String encode(byte[] bytes) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.update(bytes); + byte messageDigest[] = digest.digest(); + return ByteUtil.bytes2HexStr(messageDigest); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return ""; + } + +} diff --git a/library/src/main/java/org/davy/utils/SPUtil.java b/library/src/main/java/org/davy/utils/SPUtil.java new file mode 100644 index 0000000..3741229 --- /dev/null +++ b/library/src/main/java/org/davy/utils/SPUtil.java @@ -0,0 +1,118 @@ +package org.davy.utils; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.annotation.NonNull; + +import java.util.Map; + +public class SPUtil { + + public static final String FILE_NAME = "share_data"; + + /** + * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法 + * + * @param context + * @param key + * @param object + */ + public static void put(@NonNull Context context, String key, Object object) { + + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, + Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + + /** + * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值 + * + * @param context + * @param key + * @param defaultObject + * @return + */ + public static Object get(Context context, String key, Object defaultObject) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, + Context.MODE_PRIVATE); + + if (defaultObject instanceof String) { + return sp.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sp.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sp.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sp.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sp.getLong(key, (Long) defaultObject); + } + return null; + } + + /** + * 移除某个key值已经对应的值 + * + * @param context + * @param key + */ + public static void remove(Context context, String key) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, + Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.remove(key); + } + + /** + * 清除所有数据 + * + * @param context + */ + public static void clear(Context context) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, + Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.clear(); + } + + /** + * 查询某个key是否已经存在 + * + * @param context + * @param key + * @return + */ + public static boolean contains(Context context, String key) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, + Context.MODE_PRIVATE); + return sp.contains(key); + } + + /** + * 返回所有的键值对 + * + * @param context + * @return + */ + public static Map getAll(Context context) { + SharedPreferences sp = context.getSharedPreferences(FILE_NAME, + Context.MODE_PRIVATE); + return sp.getAll(); + } +} diff --git a/library/src/main/java/org/davy/commons/StringUtil.java b/library/src/main/java/org/davy/utils/StringUtil.java similarity index 56% rename from library/src/main/java/org/davy/commons/StringUtil.java rename to library/src/main/java/org/davy/utils/StringUtil.java index d2ba284..cb97617 100644 --- a/library/src/main/java/org/davy/commons/StringUtil.java +++ b/library/src/main/java/org/davy/utils/StringUtil.java @@ -1,6 +1,7 @@ -package org.davy.commons; +package org.davy.utils; public class StringUtil { + /** * 获取字符串的字节数目 * @param str JAVA字符串的值 @@ -50,4 +51,42 @@ public static boolean isChinese(char c) { } return false; } + + public static boolean isEmpty(final CharSequence s) { + return s == null || s.length() == 0; + } + + public static boolean isTrimEmpty(final String s) { + return (s == null || s.trim().length() == 0); + } + + public static boolean isSpace(final String s) { + if (s == null) return true; + for (int i = 0, len = s.length(); i < len; ++i) { + if (!Character.isWhitespace(s.charAt(i))) { + return false; + } + } + return true; + } + + public static boolean equals(final CharSequence s1, final CharSequence s2) { + if (s1 == s2) return true; + int length; + if (s1 != null && s2 != null && (length = s1.length()) == s2.length()) { + if (s1 instanceof String && s2 instanceof String) { + return s1.equals(s2); + } else { + for (int i = 0; i < length; i++) { + if (s1.charAt(i) != s2.charAt(i)) return false; + } + return true; + } + } + return false; + } + + public static boolean equalsIgnoreCase(final String s1, final String s2) { + return s1 == null ? s2 == null : s1.equalsIgnoreCase(s2); + } } diff --git a/library/src/main/java/org/davy/utils/SystemUtils.java b/library/src/main/java/org/davy/utils/SystemUtils.java new file mode 100644 index 0000000..0bc096b --- /dev/null +++ b/library/src/main/java/org/davy/utils/SystemUtils.java @@ -0,0 +1,146 @@ +package org.davy.utils; + +import android.os.Build; + +/** + * 获取系统信息工具类 + */ +public class SystemUtils { + + /** + * ART + * + * @return + */ + public static boolean isART() { + final String vmVersion = System.getProperty("java.vm.version"); + return vmVersion != null && vmVersion.startsWith("2"); + } + + /** + * DALVIK + * + * @return + */ + public static boolean isDalvik() { + final String vmVersion = System.getProperty("java.vm.version"); + return vmVersion != null && vmVersion.startsWith("1"); + } + + /** + * The brand (e.g., Xiaomi) the software is customized for, if any. + * + * @return + */ + public static String getBrand() { + return Build.BRAND; + } + + /** + * The name of the underlying board, like "MSM8660_SURF". + * + * @return + */ + public static String getBoard() { + return Build.BOARD; + } + + /** + * The end-user-visible name for the end product, like "MI-ONE Plus". + * + * @return + */ + public static String getModel() { + return Build.MODEL; + } + + /** + * Either a changelist number, or a label like "JZO54K". + * + * @return + */ + public static String getID() { + return Build.ID; + } + + /** + * The user-visible version string, like "4.1.2". + * + * @return + */ + public static String getVersionRelease() { + return Build.VERSION.RELEASE; + } + + /** + * The user-visible SDK version of the framework. + * + * @return + */ + public static int getVersionSDK() { + return Build.VERSION.SDK_INT; + } + + /** + * A string that uniquely identifies this build. Do not attempt to parse this value. + * + * @return + */ + public static String getFingerPrint() { + return Build.FINGERPRINT; + } + + /** + * The name of the overall product, like "mione_plus". + * + * @return + */ + public static String getProduct() { + return Build.PRODUCT; + } + + /** + * The manufacturer of the product/hardware, like "Xiaomi". + * + * @return + */ + public static String getManufacturer() { + return Build.MANUFACTURER; + } + + /** + * The name of the industrial design, like "mione_plus". + * + * @return + */ + public static String getDevice() { + return Build.DEVICE; + } + + /** + * The name of the instruction set (CPU type + ABI convention) of native code, like "armeabi-v7a". + * + * @return + */ + public static String getCpuAbi() { + return Build.CPU_ABI; + } + + /** + * The name of the second instruction set (CPU type + ABI convention) of native code, like "armeabi". + * + * @return + */ + public static String getCpuAbi2() { + return Build.CPU_ABI2; + } + + /** + * A build ID string meant for displaying to the user, like "JZO54K". + * + * @return + */ + public static String getDisplay() { + return Build.DISPLAY; + } +} diff --git a/library/src/main/java/org/davy/utils/ToastUtil.java b/library/src/main/java/org/davy/utils/ToastUtil.java new file mode 100644 index 0000000..82a644b --- /dev/null +++ b/library/src/main/java/org/davy/utils/ToastUtil.java @@ -0,0 +1,36 @@ +package org.davy.utils; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.StringRes; +import android.widget.Toast; + +/** + * @author wlj + * @date 2017/3/28 + * @email wanglijundev@gmail.com + * @packagename wanglijun.vip.androidutils + * @description Toast封装类 + */ +public class ToastUtil { + + private static Toast toast; + + public static void showToast(@NonNull Context context, String text) { + if (toast == null) { + toast = Toast.makeText(context, text, Toast.LENGTH_SHORT); + } else { + toast.setText(text); + } + toast.show(); + } + + public static void showToast(@NonNull Context context, @StringRes int resId) { + if (toast == null) { + toast = Toast.makeText(context, context.getString(resId), Toast.LENGTH_SHORT); + } else { + toast.setText(context.getString(resId)); + } + toast.show(); + } +} diff --git a/library/src/main/java/org/davy/commons/XmlUtil.java b/library/src/main/java/org/davy/utils/XmlUtil.java similarity index 92% rename from library/src/main/java/org/davy/commons/XmlUtil.java rename to library/src/main/java/org/davy/utils/XmlUtil.java index e6a8741..4ebc4d0 100644 --- a/library/src/main/java/org/davy/commons/XmlUtil.java +++ b/library/src/main/java/org/davy/utils/XmlUtil.java @@ -1,4 +1,4 @@ -package org.davy.commons; +package org.davy.utils; import org.w3c.dom.Document; import org.xml.sax.InputSource; @@ -9,6 +9,10 @@ import javax.xml.parsers.DocumentBuilderFactory; public class XmlUtil { + + private XmlUtil() { + } + public static Document parserXml(String xmlString) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { diff --git a/library/src/main/java/org/davy/utils/ZipUtils.java b/library/src/main/java/org/davy/utils/ZipUtils.java new file mode 100644 index 0000000..15b0364 --- /dev/null +++ b/library/src/main/java/org/davy/utils/ZipUtils.java @@ -0,0 +1,409 @@ +package org.davy.utils; + +import android.util.Log; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +public final class ZipUtils { + + private static final int BUFFER_LEN = 8192; + + private ZipUtils() { + } + + /** + * Zip the files. + */ + public static boolean zipFiles(final Collection srcFiles, + final String zipFilePath) + throws IOException { + return zipFiles(srcFiles, zipFilePath, null); + } + + /** + * Zip the files. + * + * @param srcFilePaths The paths of source files. + * @param zipFilePath The path of ZIP file. + * @param comment The comment. + */ + public static boolean zipFiles(final Collection srcFilePaths, + final String zipFilePath, + final String comment) + throws IOException { + if (srcFilePaths == null || zipFilePath == null) return false; + ZipOutputStream zos = null; + try { + zos = new ZipOutputStream(new FileOutputStream(zipFilePath)); + for (String srcFile : srcFilePaths) { + if (!zipFile(getFileByPath(srcFile), "", zos, comment)) return false; + } + return true; + } finally { + if (zos != null) { + zos.finish(); + zos.close(); + } + } + } + + /** + * Zip the files. + */ + public static boolean zipFiles(final Collection srcFiles, final File zipFile) + throws IOException { + return zipFiles(srcFiles, zipFile, null); + } + + /** + * Zip the files. + * + * @param srcFiles The source of files. + * @param zipFile The ZIP file. + * @param comment The comment. + */ + public static boolean zipFiles(final Collection srcFiles, + final File zipFile, + final String comment) + throws IOException { + if (srcFiles == null || zipFile == null) return false; + ZipOutputStream zos = null; + try { + zos = new ZipOutputStream(new FileOutputStream(zipFile)); + for (File srcFile : srcFiles) { + if (!zipFile(srcFile, "", zos, comment)) return false; + } + return true; + } finally { + if (zos != null) { + zos.finish(); + zos.close(); + } + } + } + + /** + * Zip the file. + * + * @param srcFilePath The path of source file. + * @param zipFilePath The path of ZIP file. + */ + public static boolean zipFile(final String srcFilePath, + final String zipFilePath) + throws IOException { + return zipFile(getFileByPath(srcFilePath), getFileByPath(zipFilePath), null); + } + + /** + * Zip the file. + * + * @param srcFilePath The path of source file. + * @param zipFilePath The path of ZIP file. + * @param comment The comment. + */ + public static boolean zipFile(final String srcFilePath, + final String zipFilePath, + final String comment) + throws IOException { + return zipFile(getFileByPath(srcFilePath), getFileByPath(zipFilePath), comment); + } + + /** + * Zip the file. + * + * @param srcFile The source of file. + * @param zipFile The ZIP file. + */ + public static boolean zipFile(final File srcFile, + final File zipFile) + throws IOException { + return zipFile(srcFile, zipFile, null); + } + + /** + * Zip the file. + * + * @param srcFile The source of file. + * @param zipFile The ZIP file. + * @param comment The comment. + */ + public static boolean zipFile(final File srcFile, + final File zipFile, + final String comment) + throws IOException { + if (srcFile == null || zipFile == null) return false; + ZipOutputStream zos = null; + try { + zos = new ZipOutputStream(new FileOutputStream(zipFile)); + return zipFile(srcFile, "", zos, comment); + } finally { + if (zos != null) { + zos.close(); + } + } + } + + private static boolean zipFile(final File srcFile, + String rootPath, + final ZipOutputStream zos, + final String comment) + throws IOException { + rootPath = rootPath + (isSpace(rootPath) ? "" : File.separator) + srcFile.getName(); + if (srcFile.isDirectory()) { + File[] fileList = srcFile.listFiles(); + if (fileList == null || fileList.length <= 0) { + ZipEntry entry = new ZipEntry(rootPath + '/'); + entry.setComment(comment); + zos.putNextEntry(entry); + zos.closeEntry(); + } else { + for (File file : fileList) { + if (!zipFile(file, rootPath, zos, comment)) return false; + } + } + } else { + InputStream is = null; + try { + is = new BufferedInputStream(new FileInputStream(srcFile)); + ZipEntry entry = new ZipEntry(rootPath); + entry.setComment(comment); + zos.putNextEntry(entry); + byte buffer[] = new byte[BUFFER_LEN]; + int len; + while ((len = is.read(buffer, 0, BUFFER_LEN)) != -1) { + zos.write(buffer, 0, len); + } + zos.closeEntry(); + } finally { + if (is != null) { + is.close(); + } + } + } + return true; + } + + /** + * Unzip the file. + * + * @param zipFilePath The path of ZIP file. + * @param destDirPath The path of destination directory. + */ + public static List unzipFile(final String zipFilePath, + final String destDirPath) + throws IOException { + return unzipFileByKeyword(zipFilePath, destDirPath, null); + } + + /** + * Unzip the file. + * + * @param zipFile The ZIP file. + * @param destDir The destination directory. + * @return the unzipped files + * @throws IOException if unzip unsuccessfully + */ + public static List unzipFile(final File zipFile, + final File destDir) + throws IOException { + return unzipFileByKeyword(zipFile, destDir, null); + } + + /** + * Unzip the file by keyword. + * + * @param zipFilePath The path of ZIP file. + * @param destDirPath The path of destination directory. + * @param keyword The keyboard. + * @return the unzipped files + * @throws IOException if unzip unsuccessfully + */ + public static List unzipFileByKeyword(final String zipFilePath, + final String destDirPath, + final String keyword) + throws IOException { + return unzipFileByKeyword(getFileByPath(zipFilePath), getFileByPath(destDirPath), keyword); + } + + /** + * Unzip the file by keyword. + * + * @param zipFile The ZIP file. + * @param destDir The destination directory. + * @param keyword The keyboard. + * @return the unzipped files + * @throws IOException if unzip unsuccessfully + */ + public static List unzipFileByKeyword(final File zipFile, + final File destDir, + final String keyword) + throws IOException { + if (zipFile == null || destDir == null) return null; + List files = new ArrayList<>(); + ZipFile zf = new ZipFile(zipFile); + Enumeration entries = zf.entries(); + if (isSpace(keyword)) { + while (entries.hasMoreElements()) { + ZipEntry entry = ((ZipEntry) entries.nextElement()); + String entryName = entry.getName(); + if (entryName.contains("../")) { + Log.e("ZipUtils", "it's dangerous!"); + return files; + } + if (!unzipChildFile(destDir, files, zf, entry, entryName)) return files; + } + } else { + while (entries.hasMoreElements()) { + ZipEntry entry = ((ZipEntry) entries.nextElement()); + String entryName = entry.getName(); + if (entryName.contains("../")) { + Log.e("ZipUtils", "it's dangerous!"); + return files; + } + if (entryName.contains(keyword)) { + if (!unzipChildFile(destDir, files, zf, entry, entryName)) return files; + } + } + } + return files; + } + + private static boolean unzipChildFile(final File destDir, + final List files, + final ZipFile zf, + final ZipEntry entry, + final String entryName) throws IOException { + String filePath = destDir + File.separator + entryName; + File file = new File(filePath); + files.add(file); + if (entry.isDirectory()) { + if (!createOrExistsDir(file)) return false; + } else { + if (!createOrExistsFile(file)) return false; + InputStream in = null; + OutputStream out = null; + try { + in = new BufferedInputStream(zf.getInputStream(entry)); + out = new BufferedOutputStream(new FileOutputStream(file)); + byte buffer[] = new byte[BUFFER_LEN]; + int len; + while ((len = in.read(buffer)) != -1) { + out.write(buffer, 0, len); + } + } finally { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + } + } + return true; + } + + /** + * Return the files' path in ZIP file. + * + * @param zipFilePath The path of ZIP file. + * @return the files' path in ZIP file + * @throws IOException if an I/O error has occurred + */ + public static List getFilesPath(final String zipFilePath) + throws IOException { + return getFilesPath(getFileByPath(zipFilePath)); + } + + /** + * Return the files' path in ZIP file. + * + * @param zipFile The ZIP file. + * @return the files' path in ZIP file + * @throws IOException if an I/O error has occurred + */ + public static List getFilesPath(final File zipFile) + throws IOException { + if (zipFile == null) return null; + List paths = new ArrayList<>(); + Enumeration entries = new ZipFile(zipFile).entries(); + while (entries.hasMoreElements()) { + paths.add(((ZipEntry) entries.nextElement()).getName()); + } + return paths; + } + + /** + * Return the files' comment in ZIP file. + * + * @param zipFilePath The path of ZIP file. + * @return the files' comment in ZIP file + * @throws IOException if an I/O error has occurred + */ + public static List getComments(final String zipFilePath) + throws IOException { + return getComments(getFileByPath(zipFilePath)); + } + + /** + * Return the files' comment in ZIP file. + * + * @param zipFile The ZIP file. + * @return the files' comment in ZIP file + * @throws IOException if an I/O error has occurred + */ + public static List getComments(final File zipFile) + throws IOException { + if (zipFile == null) return null; + List comments = new ArrayList<>(); + Enumeration entries = new ZipFile(zipFile).entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = ((ZipEntry) entries.nextElement()); + comments.add(entry.getComment()); + } + return comments; + } + + private static boolean createOrExistsDir(final File file) { + return file != null && (file.exists() ? file.isDirectory() : file.mkdirs()); + } + + private static boolean createOrExistsFile(final File file) { + if (file == null) return false; + if (file.exists()) return file.isFile(); + if (!createOrExistsDir(file.getParentFile())) return false; + try { + return file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + private static File getFileByPath(final String filePath) { + return isSpace(filePath) ? null : new File(filePath); + } + + private static boolean isSpace(final String s) { + if (s == null) return true; + for (int i = 0, len = s.length(); i < len; ++i) { + if (!Character.isWhitespace(s.charAt(i))) { + return false; + } + } + return true; + } +} diff --git a/buildSrc/.gitignore b/plugin/.gitignore similarity index 100% rename from buildSrc/.gitignore rename to plugin/.gitignore diff --git a/buildSrc/build.gradle b/plugin/build.gradle similarity index 100% rename from buildSrc/build.gradle rename to plugin/build.gradle diff --git a/buildsrc/src/main/groovy/org/davy/commons/plugin/InjectPlugin.groovy b/plugin/src/main/groovy/org/davy/utils/plugin/InjectPlugin.groovy similarity index 93% rename from buildsrc/src/main/groovy/org/davy/commons/plugin/InjectPlugin.groovy rename to plugin/src/main/groovy/org/davy/utils/plugin/InjectPlugin.groovy index b217af4..bc633c6 100644 --- a/buildsrc/src/main/groovy/org/davy/commons/plugin/InjectPlugin.groovy +++ b/plugin/src/main/groovy/org/davy/utils/plugin/InjectPlugin.groovy @@ -1,4 +1,4 @@ -package org.davy.commons.plugin; +package org.davy.utils.plugin; import org.gradle.api.Plugin import org.gradle.api.Project diff --git a/buildsrc/src/main/groovy/org/davy/commons/plugin/InjectTransform.groovy b/plugin/src/main/groovy/org/davy/utils/plugin/InjectTransform.groovy similarity index 99% rename from buildsrc/src/main/groovy/org/davy/commons/plugin/InjectTransform.groovy rename to plugin/src/main/groovy/org/davy/utils/plugin/InjectTransform.groovy index fb42b66..d4e1937 100644 --- a/buildsrc/src/main/groovy/org/davy/commons/plugin/InjectTransform.groovy +++ b/plugin/src/main/groovy/org/davy/utils/plugin/InjectTransform.groovy @@ -1,4 +1,4 @@ -package org.davy.commons.plugin +package org.davy.utils.plugin import com.android.build.api.transform.* import com.android.build.gradle.internal.pipeline.TransformManager diff --git a/buildsrc/src/main/groovy/org/davy/commons/plugin/MyInject.groovy b/plugin/src/main/groovy/org/davy/utils/plugin/MyInject.groovy similarity index 98% rename from buildsrc/src/main/groovy/org/davy/commons/plugin/MyInject.groovy rename to plugin/src/main/groovy/org/davy/utils/plugin/MyInject.groovy index cb6cc9d..78c3486 100644 --- a/buildsrc/src/main/groovy/org/davy/commons/plugin/MyInject.groovy +++ b/plugin/src/main/groovy/org/davy/utils/plugin/MyInject.groovy @@ -1,4 +1,4 @@ -package org.davy.commons.plugin +package org.davy.utils.plugin /** * Created by davy on 2017/6/8. diff --git a/buildsrc/src/main/groovy/org/davy/commons/plugin/OnlyCopyTransform.groovy b/plugin/src/main/groovy/org/davy/utils/plugin/OnlyCopyTransform.groovy similarity index 99% rename from buildsrc/src/main/groovy/org/davy/commons/plugin/OnlyCopyTransform.groovy rename to plugin/src/main/groovy/org/davy/utils/plugin/OnlyCopyTransform.groovy index 82a1335..28d7476 100644 --- a/buildsrc/src/main/groovy/org/davy/commons/plugin/OnlyCopyTransform.groovy +++ b/plugin/src/main/groovy/org/davy/utils/plugin/OnlyCopyTransform.groovy @@ -1,4 +1,4 @@ -package org.davy.commons.plugin +package org.davy.utils.plugin import com.android.build.api.transform.* import com.android.build.gradle.internal.pipeline.TransformManager diff --git a/samples/build.gradle b/samples/build.gradle index b37857f..11b1d28 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -1,6 +1,4 @@ apply plugin: 'com.android.application' -//apply plugin: 'org.davy.commons.gradle' -apply plugin: org.davy.commons.plugin.InjectPlugin android { compileSdkVersion 25 @@ -28,7 +26,7 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' }) compile project(':library') - compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:appcompat-v7:25.4.0' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' } diff --git a/samples/src/androidTest/java/org/davy/commons/samples/ExampleInstrumentedTest.java b/samples/src/androidTest/java/org/davy/utils/samples/ExampleInstrumentedTest.java similarity index 95% rename from samples/src/androidTest/java/org/davy/commons/samples/ExampleInstrumentedTest.java rename to samples/src/androidTest/java/org/davy/utils/samples/ExampleInstrumentedTest.java index 1449e7b..d601b01 100644 --- a/samples/src/androidTest/java/org/davy/commons/samples/ExampleInstrumentedTest.java +++ b/samples/src/androidTest/java/org/davy/utils/samples/ExampleInstrumentedTest.java @@ -1,4 +1,4 @@ -package org.davy.commons.samples; +package org.davy.utils.samples; import android.content.Context; import android.support.test.InstrumentationRegistry; diff --git a/samples/src/main/AndroidManifest.xml b/samples/src/main/AndroidManifest.xml index 713b3f2..124e271 100644 --- a/samples/src/main/AndroidManifest.xml +++ b/samples/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + package="org.davy.utils.samples"> diff --git a/samples/src/main/java/org/davy/commons/samples/Test.java b/samples/src/main/java/org/davy/commons/samples/Test.java deleted file mode 100644 index 30d1e67..0000000 --- a/samples/src/main/java/org/davy/commons/samples/Test.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.davy.commons.samples; - -import org.davy.commons.samples.Utils; - -/** - * Created by davy on 2017/6/9. - */ - -public class Test { - public void show() { - System.out.println(Utils.getLineNumber()); - } -} diff --git a/samples/src/main/java/org/davy/commons/samples/MainActivity.java b/samples/src/main/java/org/davy/utils/samples/MainActivity.java similarity index 68% rename from samples/src/main/java/org/davy/commons/samples/MainActivity.java rename to samples/src/main/java/org/davy/utils/samples/MainActivity.java index 1b0d301..f805adc 100644 --- a/samples/src/main/java/org/davy/commons/samples/MainActivity.java +++ b/samples/src/main/java/org/davy/utils/samples/MainActivity.java @@ -1,28 +1,21 @@ -package org.davy.commons.samples; +package org.davy.utils.samples; -import android.content.res.AssetManager; -import android.support.v7.app.AppCompatActivity; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageInfo; import android.os.Bundle; -import android.util.Xml; +import android.support.v7.app.AppCompatActivity; import android.widget.Toast; -import org.davy.commons.FileUtils; -import org.davy.commons.IOUtils; -import org.davy.commons.NetworkUtil; -import org.davy.commons.XmlUtil; +import org.davy.utils.IOUtils; +import org.davy.utils.NetworkUtil; +import org.davy.utils.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import org.xml.sax.InputSource; -import java.io.ByteArrayInputStream; -import java.io.File; import java.io.IOException; import java.io.InputStream; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - public class MainActivity extends AppCompatActivity { @Override @@ -30,6 +23,10 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + PackageInfo packageInfo = getPackageManager().getPackageArchiveInfo("", 0); + ActivityInfo[] activities = packageInfo.activities; + activities[0].getThemeResource(); + Toast.makeText(this, NetworkUtil.getCurrentIp(this), Toast.LENGTH_LONG).show(); InputStream inputStream = null; try { @@ -38,7 +35,7 @@ protected void onCreate(Bundle savedInstanceState) { byte[] datas = new byte[length]; getAssets().open("AndroidManifest.xml").read(datas); String content = new String(datas); - content =content.replaceAll("\\s*\n\\s*",""); + content = content.replaceAll("\\s*\n\\s*", ""); System.out.println(content); Document document = XmlUtil.parserXml(content); System.out.println(document.getXmlEncoding() + "-" + document.getXmlVersion() + "-" + document.getXmlStandalone()); @@ -50,9 +47,6 @@ protected void onCreate(Bundle savedInstanceState) { } finally { IOUtils.closeQuietly(inputStream); } - - Test test = new Test(); - test.show(); } private String nodeType2String(short type) { @@ -98,24 +92,24 @@ private String nodeType2String(short type) { return str; } - private void printNode(String prex, Node node, StringBuilder stringBuilder){ - if (node == null) { - return; - } - stringBuilder.append(prex).append("name:" + node.getNodeName() + " \n") - .append(prex).append("type:" + nodeType2String(node.getNodeType()) + " \n") - .append(prex).append("value:" + node.getNodeValue() + " \n") - .append(prex).append("nsUrl:" + node.getNamespaceURI() + " \n") - .append(prex).append("Attrs:\n" + printNodeMap(node.getAttributes()) + " \n"); + private void printNode(String prex, Node node, StringBuilder stringBuilder) { + if (node == null) { + return; + } + stringBuilder.append(prex).append("name:" + node.getNodeName() + " \n") + .append(prex).append("type:" + nodeType2String(node.getNodeType()) + " \n") + .append(prex).append("value:" + node.getNodeValue() + " \n") + .append(prex).append("nsUrl:" + node.getNamespaceURI() + " \n") + .append(prex).append("Attrs:\n" + printNodeMap(node.getAttributes()) + " \n"); - if (node.getChildNodes() != null && node.getChildNodes().getLength() > 0 ) { - for (int i = 0; i < node.getChildNodes().getLength(); i++) { - printNode(prex + "=",node.getChildNodes().item(i), stringBuilder); - } - } - } + if (node.getChildNodes() != null && node.getChildNodes().getLength() > 0) { + for (int i = 0; i < node.getChildNodes().getLength(); i++) { + printNode(prex + "=", node.getChildNodes().item(i), stringBuilder); + } + } + } - private String printNodeMap(NamedNodeMap nodemap){ + private String printNodeMap(NamedNodeMap nodemap) { if (nodemap == null) { return "\n"; } diff --git a/samples/src/main/res/layout/activity_main.xml b/samples/src/main/res/layout/activity_main.xml index d28508d..7c01b8c 100644 --- a/samples/src/main/res/layout/activity_main.xml +++ b/samples/src/main/res/layout/activity_main.xml @@ -4,6 +4,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="org.davy.commons.samples.MainActivity"> + tools:context="org.davy.utils.samples.MainActivity"> diff --git a/samples/src/test/java/org/davy/commons/samples/ExampleUnitTest.java b/samples/src/test/java/org/davy/commons/samples/ExampleUnitTest.java deleted file mode 100644 index c530269..0000000 --- a/samples/src/test/java/org/davy/commons/samples/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.davy.commons.samples; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/library/src/test/java/org/davy/commons/ExampleUnitTest.java b/samples/src/test/java/org/davy/utils/samples/ExampleUnitTest.java similarity index 92% rename from library/src/test/java/org/davy/commons/ExampleUnitTest.java rename to samples/src/test/java/org/davy/utils/samples/ExampleUnitTest.java index 89a0b08..7a03b21 100644 --- a/library/src/test/java/org/davy/commons/ExampleUnitTest.java +++ b/samples/src/test/java/org/davy/utils/samples/ExampleUnitTest.java @@ -1,4 +1,4 @@ -package org.davy.commons; +package org.davy.utils.samples; import org.junit.Test; diff --git a/settings.gradle b/settings.gradle index 9fd82e1..e4c75e6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':samples', ':library', ':buildsrc' +include ':samples', ':library', ':plugin' From 3d1233698599ec0cacdbe19d0738885ea1b7b7ef Mon Sep 17 00:00:00 2001 From: wangyh <1051522865@qq.com> Date: Fri, 8 Jun 2018 01:30:25 +0800 Subject: [PATCH 03/13] rename package --- .idea/caches/build_file_checksums.ser | Bin 642 -> 642 bytes library/src/main/AndroidManifest.xml | 2 +- .../org/{davy => greenleaf}/utils/AppUtils.java | 2 +- .../{davy => greenleaf}/utils/AssetsUtils.java | 2 +- .../{davy => greenleaf}/utils/Base64Utils.java | 2 +- .../{davy => greenleaf}/utils/BitmapUtils.java | 2 +- .../org/{davy => greenleaf}/utils/ByteUtil.java | 2 +- .../utils/CollectionUtils.java | 2 +- .../{davy => greenleaf}/utils/DisplayUtils.java | 2 +- .../{davy => greenleaf}/utils/DumpUtils.java | 2 +- .../{davy => greenleaf}/utils/FileUtils.java | 2 +- .../org/{davy => greenleaf}/utils/IOUtils.java | 2 +- .../org/{davy => greenleaf}/utils/MD5Utils.java | 2 +- .../{davy => greenleaf}/utils/NetworkUtil.java | 2 +- .../{davy => greenleaf}/utils/NumberUtils.java | 2 +- .../{davy => greenleaf}/utils/ObjectUtils.java | 2 +- .../{davy => greenleaf}/utils/PackageUtils.java | 2 +- .../{davy => greenleaf}/utils/RandomUtils.java | 2 +- .../{davy => greenleaf}/utils/RegexUtils.java | 2 +- .../{davy => greenleaf}/utils/SHA1Utils.java | 2 +- .../org/{davy => greenleaf}/utils/SPUtil.java | 2 +- .../{davy => greenleaf}/utils/StringUtil.java | 2 +- .../{davy => greenleaf}/utils/SystemUtils.java | 2 +- .../{davy => greenleaf}/utils/ToastUtil.java | 2 +- .../org/{davy => greenleaf}/utils/XmlUtil.java | 2 +- .../org/{davy => greenleaf}/utils/ZipUtils.java | 2 +- plugin/build.gradle | 1 - .../utils/plugin/InjectPlugin.groovy | 2 +- .../utils/plugin/InjectTransform.groovy | 2 +- .../utils/plugin/MyInject.groovy | 2 +- .../utils/plugin/OnlyCopyTransform.groovy | 2 +- .../utils/samples/ExampleInstrumentedTest.java | 2 +- samples/src/main/AndroidManifest.xml | 2 +- .../utils/samples/MainActivity.java | 8 ++++---- samples/src/main/res/layout/activity_main.xml | 2 +- .../utils/samples/ExampleUnitTest.java | 2 +- 36 files changed, 37 insertions(+), 38 deletions(-) rename library/src/main/java/org/{davy => greenleaf}/utils/AppUtils.java (99%) rename library/src/main/java/org/{davy => greenleaf}/utils/AssetsUtils.java (98%) rename library/src/main/java/org/{davy => greenleaf}/utils/Base64Utils.java (96%) rename library/src/main/java/org/{davy => greenleaf}/utils/BitmapUtils.java (98%) rename library/src/main/java/org/{davy => greenleaf}/utils/ByteUtil.java (98%) rename library/src/main/java/org/{davy => greenleaf}/utils/CollectionUtils.java (98%) rename library/src/main/java/org/{davy => greenleaf}/utils/DisplayUtils.java (99%) rename library/src/main/java/org/{davy => greenleaf}/utils/DumpUtils.java (96%) rename library/src/main/java/org/{davy => greenleaf}/utils/FileUtils.java (99%) rename library/src/main/java/org/{davy => greenleaf}/utils/IOUtils.java (98%) rename library/src/main/java/org/{davy => greenleaf}/utils/MD5Utils.java (96%) rename library/src/main/java/org/{davy => greenleaf}/utils/NetworkUtil.java (98%) rename library/src/main/java/org/{davy => greenleaf}/utils/NumberUtils.java (95%) rename library/src/main/java/org/{davy => greenleaf}/utils/ObjectUtils.java (82%) rename library/src/main/java/org/{davy => greenleaf}/utils/PackageUtils.java (99%) rename library/src/main/java/org/{davy => greenleaf}/utils/RandomUtils.java (97%) rename library/src/main/java/org/{davy => greenleaf}/utils/RegexUtils.java (98%) rename library/src/main/java/org/{davy => greenleaf}/utils/SHA1Utils.java (96%) rename library/src/main/java/org/{davy => greenleaf}/utils/SPUtil.java (99%) rename library/src/main/java/org/{davy => greenleaf}/utils/StringUtil.java (98%) rename library/src/main/java/org/{davy => greenleaf}/utils/SystemUtils.java (99%) rename library/src/main/java/org/{davy => greenleaf}/utils/ToastUtil.java (96%) rename library/src/main/java/org/{davy => greenleaf}/utils/XmlUtil.java (96%) rename library/src/main/java/org/{davy => greenleaf}/utils/ZipUtils.java (99%) rename plugin/src/main/groovy/org/{davy => greenleaf}/utils/plugin/InjectPlugin.groovy (93%) rename plugin/src/main/groovy/org/{davy => greenleaf}/utils/plugin/InjectTransform.groovy (98%) rename plugin/src/main/groovy/org/{davy => greenleaf}/utils/plugin/MyInject.groovy (98%) rename plugin/src/main/groovy/org/{davy => greenleaf}/utils/plugin/OnlyCopyTransform.groovy (98%) rename samples/src/androidTest/java/org/{davy => greenleaf}/utils/samples/ExampleInstrumentedTest.java (95%) rename samples/src/main/java/org/{davy => greenleaf}/utils/samples/MainActivity.java (96%) rename samples/src/test/java/org/{davy => greenleaf}/utils/samples/ExampleUnitTest.java (90%) diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 3aeb1378bf6956ff4e94d0014fd85287f1573589..32aa9b4c4a9670dd71e3c940cee56a0bda7fdb5b 100644 GIT binary patch delta 36 ucmV+<0Nek91%d^Tm;~EOz#WmCdJw5o6Yvego4ef~m-4RrD9N)X0bBtmUJ!2p delta 36 scmZo-ZDO4;gXPva<~I}PR0$|vKIK2Z*K9_Gx*|VQ?4_TZ)fi(K0Umh{zyJUM diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml index 81812c0..016c7c9 100644 --- a/library/src/main/AndroidManifest.xml +++ b/library/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="org.greenleaf.utils"> diff --git a/library/src/main/java/org/davy/utils/AppUtils.java b/library/src/main/java/org/greenleaf/utils/AppUtils.java similarity index 99% rename from library/src/main/java/org/davy/utils/AppUtils.java rename to library/src/main/java/org/greenleaf/utils/AppUtils.java index 46bfce4..7a0993b 100644 --- a/library/src/main/java/org/davy/utils/AppUtils.java +++ b/library/src/main/java/org/greenleaf/utils/AppUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.app.ActivityManager; import android.content.ComponentName; diff --git a/library/src/main/java/org/davy/utils/AssetsUtils.java b/library/src/main/java/org/greenleaf/utils/AssetsUtils.java similarity index 98% rename from library/src/main/java/org/davy/utils/AssetsUtils.java rename to library/src/main/java/org/greenleaf/utils/AssetsUtils.java index 577a842..4c6195b 100644 --- a/library/src/main/java/org/davy/utils/AssetsUtils.java +++ b/library/src/main/java/org/greenleaf/utils/AssetsUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.content.Context; import android.content.res.AssetManager; diff --git a/library/src/main/java/org/davy/utils/Base64Utils.java b/library/src/main/java/org/greenleaf/utils/Base64Utils.java similarity index 96% rename from library/src/main/java/org/davy/utils/Base64Utils.java rename to library/src/main/java/org/greenleaf/utils/Base64Utils.java index f7edac5..7efc6e7 100644 --- a/library/src/main/java/org/davy/utils/Base64Utils.java +++ b/library/src/main/java/org/greenleaf/utils/Base64Utils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.util.Base64; diff --git a/library/src/main/java/org/davy/utils/BitmapUtils.java b/library/src/main/java/org/greenleaf/utils/BitmapUtils.java similarity index 98% rename from library/src/main/java/org/davy/utils/BitmapUtils.java rename to library/src/main/java/org/greenleaf/utils/BitmapUtils.java index 46228df..68ba12f 100644 --- a/library/src/main/java/org/davy/utils/BitmapUtils.java +++ b/library/src/main/java/org/greenleaf/utils/BitmapUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.graphics.Bitmap; import android.graphics.Canvas; diff --git a/library/src/main/java/org/davy/utils/ByteUtil.java b/library/src/main/java/org/greenleaf/utils/ByteUtil.java similarity index 98% rename from library/src/main/java/org/davy/utils/ByteUtil.java rename to library/src/main/java/org/greenleaf/utils/ByteUtil.java index 54d99a6..a9ecdd1 100644 --- a/library/src/main/java/org/davy/utils/ByteUtil.java +++ b/library/src/main/java/org/greenleaf/utils/ByteUtil.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import java.util.Locale; diff --git a/library/src/main/java/org/davy/utils/CollectionUtils.java b/library/src/main/java/org/greenleaf/utils/CollectionUtils.java similarity index 98% rename from library/src/main/java/org/davy/utils/CollectionUtils.java rename to library/src/main/java/org/greenleaf/utils/CollectionUtils.java index 2c440dc..ef84231 100644 --- a/library/src/main/java/org/davy/utils/CollectionUtils.java +++ b/library/src/main/java/org/greenleaf/utils/CollectionUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.text.TextUtils; diff --git a/library/src/main/java/org/davy/utils/DisplayUtils.java b/library/src/main/java/org/greenleaf/utils/DisplayUtils.java similarity index 99% rename from library/src/main/java/org/davy/utils/DisplayUtils.java rename to library/src/main/java/org/greenleaf/utils/DisplayUtils.java index fee4a99..bb43405 100644 --- a/library/src/main/java/org/davy/utils/DisplayUtils.java +++ b/library/src/main/java/org/greenleaf/utils/DisplayUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.app.Activity; import android.content.Context; diff --git a/library/src/main/java/org/davy/utils/DumpUtils.java b/library/src/main/java/org/greenleaf/utils/DumpUtils.java similarity index 96% rename from library/src/main/java/org/davy/utils/DumpUtils.java rename to library/src/main/java/org/greenleaf/utils/DumpUtils.java index dc3f6a8..3123407 100644 --- a/library/src/main/java/org/davy/utils/DumpUtils.java +++ b/library/src/main/java/org/greenleaf/utils/DumpUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; public class DumpUtils { diff --git a/library/src/main/java/org/davy/utils/FileUtils.java b/library/src/main/java/org/greenleaf/utils/FileUtils.java similarity index 99% rename from library/src/main/java/org/davy/utils/FileUtils.java rename to library/src/main/java/org/greenleaf/utils/FileUtils.java index 4b5fbdd..a48d0cd 100644 --- a/library/src/main/java/org/davy/utils/FileUtils.java +++ b/library/src/main/java/org/greenleaf/utils/FileUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.davy.utils; +package org.greenleaf.utils; import java.io.File; import java.io.FileFilter; diff --git a/library/src/main/java/org/davy/utils/IOUtils.java b/library/src/main/java/org/greenleaf/utils/IOUtils.java similarity index 98% rename from library/src/main/java/org/davy/utils/IOUtils.java rename to library/src/main/java/org/greenleaf/utils/IOUtils.java index dd58d0e..53db4de 100644 --- a/library/src/main/java/org/davy/utils/IOUtils.java +++ b/library/src/main/java/org/greenleaf/utils/IOUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.davy.utils; +package org.greenleaf.utils; import java.io.Closeable; import java.io.IOException; diff --git a/library/src/main/java/org/davy/utils/MD5Utils.java b/library/src/main/java/org/greenleaf/utils/MD5Utils.java similarity index 96% rename from library/src/main/java/org/davy/utils/MD5Utils.java rename to library/src/main/java/org/greenleaf/utils/MD5Utils.java index b44e9d1..3f47a95 100644 --- a/library/src/main/java/org/davy/utils/MD5Utils.java +++ b/library/src/main/java/org/greenleaf/utils/MD5Utils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; diff --git a/library/src/main/java/org/davy/utils/NetworkUtil.java b/library/src/main/java/org/greenleaf/utils/NetworkUtil.java similarity index 98% rename from library/src/main/java/org/davy/utils/NetworkUtil.java rename to library/src/main/java/org/greenleaf/utils/NetworkUtil.java index e974dbc..02f015d 100644 --- a/library/src/main/java/org/davy/utils/NetworkUtil.java +++ b/library/src/main/java/org/greenleaf/utils/NetworkUtil.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.content.Context; import android.net.ConnectivityManager; diff --git a/library/src/main/java/org/davy/utils/NumberUtils.java b/library/src/main/java/org/greenleaf/utils/NumberUtils.java similarity index 95% rename from library/src/main/java/org/davy/utils/NumberUtils.java rename to library/src/main/java/org/greenleaf/utils/NumberUtils.java index 480a072..03a1281 100644 --- a/library/src/main/java/org/davy/utils/NumberUtils.java +++ b/library/src/main/java/org/greenleaf/utils/NumberUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import java.text.DecimalFormat; diff --git a/library/src/main/java/org/davy/utils/ObjectUtils.java b/library/src/main/java/org/greenleaf/utils/ObjectUtils.java similarity index 82% rename from library/src/main/java/org/davy/utils/ObjectUtils.java rename to library/src/main/java/org/greenleaf/utils/ObjectUtils.java index 7d59ab0..be9447e 100644 --- a/library/src/main/java/org/davy/utils/ObjectUtils.java +++ b/library/src/main/java/org/greenleaf/utils/ObjectUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; public class ObjectUtils { diff --git a/library/src/main/java/org/davy/utils/PackageUtils.java b/library/src/main/java/org/greenleaf/utils/PackageUtils.java similarity index 99% rename from library/src/main/java/org/davy/utils/PackageUtils.java rename to library/src/main/java/org/greenleaf/utils/PackageUtils.java index 5eba5df..838b56e 100644 --- a/library/src/main/java/org/davy/utils/PackageUtils.java +++ b/library/src/main/java/org/greenleaf/utils/PackageUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.content.ComponentName; import android.content.Context; diff --git a/library/src/main/java/org/davy/utils/RandomUtils.java b/library/src/main/java/org/greenleaf/utils/RandomUtils.java similarity index 97% rename from library/src/main/java/org/davy/utils/RandomUtils.java rename to library/src/main/java/org/greenleaf/utils/RandomUtils.java index c25a46f..896ad6b 100644 --- a/library/src/main/java/org/davy/utils/RandomUtils.java +++ b/library/src/main/java/org/greenleaf/utils/RandomUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import java.util.Random; diff --git a/library/src/main/java/org/davy/utils/RegexUtils.java b/library/src/main/java/org/greenleaf/utils/RegexUtils.java similarity index 98% rename from library/src/main/java/org/davy/utils/RegexUtils.java rename to library/src/main/java/org/greenleaf/utils/RegexUtils.java index 280d8a0..5d4fa52 100644 --- a/library/src/main/java/org/davy/utils/RegexUtils.java +++ b/library/src/main/java/org/greenleaf/utils/RegexUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/library/src/main/java/org/davy/utils/SHA1Utils.java b/library/src/main/java/org/greenleaf/utils/SHA1Utils.java similarity index 96% rename from library/src/main/java/org/davy/utils/SHA1Utils.java rename to library/src/main/java/org/greenleaf/utils/SHA1Utils.java index e21e32e..510a354 100644 --- a/library/src/main/java/org/davy/utils/SHA1Utils.java +++ b/library/src/main/java/org/greenleaf/utils/SHA1Utils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; diff --git a/library/src/main/java/org/davy/utils/SPUtil.java b/library/src/main/java/org/greenleaf/utils/SPUtil.java similarity index 99% rename from library/src/main/java/org/davy/utils/SPUtil.java rename to library/src/main/java/org/greenleaf/utils/SPUtil.java index 3741229..12cda3e 100644 --- a/library/src/main/java/org/davy/utils/SPUtil.java +++ b/library/src/main/java/org/greenleaf/utils/SPUtil.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.content.Context; import android.content.SharedPreferences; diff --git a/library/src/main/java/org/davy/utils/StringUtil.java b/library/src/main/java/org/greenleaf/utils/StringUtil.java similarity index 98% rename from library/src/main/java/org/davy/utils/StringUtil.java rename to library/src/main/java/org/greenleaf/utils/StringUtil.java index cb97617..9acc1d0 100644 --- a/library/src/main/java/org/davy/utils/StringUtil.java +++ b/library/src/main/java/org/greenleaf/utils/StringUtil.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; public class StringUtil { diff --git a/library/src/main/java/org/davy/utils/SystemUtils.java b/library/src/main/java/org/greenleaf/utils/SystemUtils.java similarity index 99% rename from library/src/main/java/org/davy/utils/SystemUtils.java rename to library/src/main/java/org/greenleaf/utils/SystemUtils.java index 0bc096b..1463f73 100644 --- a/library/src/main/java/org/davy/utils/SystemUtils.java +++ b/library/src/main/java/org/greenleaf/utils/SystemUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.os.Build; diff --git a/library/src/main/java/org/davy/utils/ToastUtil.java b/library/src/main/java/org/greenleaf/utils/ToastUtil.java similarity index 96% rename from library/src/main/java/org/davy/utils/ToastUtil.java rename to library/src/main/java/org/greenleaf/utils/ToastUtil.java index 82a644b..0232a0c 100644 --- a/library/src/main/java/org/davy/utils/ToastUtil.java +++ b/library/src/main/java/org/greenleaf/utils/ToastUtil.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.content.Context; import android.support.annotation.NonNull; diff --git a/library/src/main/java/org/davy/utils/XmlUtil.java b/library/src/main/java/org/greenleaf/utils/XmlUtil.java similarity index 96% rename from library/src/main/java/org/davy/utils/XmlUtil.java rename to library/src/main/java/org/greenleaf/utils/XmlUtil.java index 4ebc4d0..b0ccbc6 100644 --- a/library/src/main/java/org/davy/utils/XmlUtil.java +++ b/library/src/main/java/org/greenleaf/utils/XmlUtil.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import org.w3c.dom.Document; import org.xml.sax.InputSource; diff --git a/library/src/main/java/org/davy/utils/ZipUtils.java b/library/src/main/java/org/greenleaf/utils/ZipUtils.java similarity index 99% rename from library/src/main/java/org/davy/utils/ZipUtils.java rename to library/src/main/java/org/greenleaf/utils/ZipUtils.java index 15b0364..5adf418 100644 --- a/library/src/main/java/org/davy/utils/ZipUtils.java +++ b/library/src/main/java/org/greenleaf/utils/ZipUtils.java @@ -1,4 +1,4 @@ -package org.davy.utils; +package org.greenleaf.utils; import android.util.Log; diff --git a/plugin/build.gradle b/plugin/build.gradle index 61d6151..faa8e95 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -2,7 +2,6 @@ apply plugin: 'groovy' dependencies { compile gradleApi()//gradle sdk - //compile localGroovy()//groovy sdk compile 'com.android.tools.build:gradle:2.3.1' compile 'org.javassist:javassist:3.20.0-GA' } diff --git a/plugin/src/main/groovy/org/davy/utils/plugin/InjectPlugin.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy similarity index 93% rename from plugin/src/main/groovy/org/davy/utils/plugin/InjectPlugin.groovy rename to plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy index bc633c6..266231b 100644 --- a/plugin/src/main/groovy/org/davy/utils/plugin/InjectPlugin.groovy +++ b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy @@ -1,4 +1,4 @@ -package org.davy.utils.plugin; +package org.greenleaf.utils.plugin; import org.gradle.api.Plugin import org.gradle.api.Project diff --git a/plugin/src/main/groovy/org/davy/utils/plugin/InjectTransform.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy similarity index 98% rename from plugin/src/main/groovy/org/davy/utils/plugin/InjectTransform.groovy rename to plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy index d4e1937..dd8b8a7 100644 --- a/plugin/src/main/groovy/org/davy/utils/plugin/InjectTransform.groovy +++ b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy @@ -1,4 +1,4 @@ -package org.davy.utils.plugin +package org.greenleaf.utils.plugin import com.android.build.api.transform.* import com.android.build.gradle.internal.pipeline.TransformManager diff --git a/plugin/src/main/groovy/org/davy/utils/plugin/MyInject.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/MyInject.groovy similarity index 98% rename from plugin/src/main/groovy/org/davy/utils/plugin/MyInject.groovy rename to plugin/src/main/groovy/org/greenleaf/utils/plugin/MyInject.groovy index 78c3486..8e4c026 100644 --- a/plugin/src/main/groovy/org/davy/utils/plugin/MyInject.groovy +++ b/plugin/src/main/groovy/org/greenleaf/utils/plugin/MyInject.groovy @@ -1,4 +1,4 @@ -package org.davy.utils.plugin +package org.greenleaf.utils.plugin /** * Created by davy on 2017/6/8. diff --git a/plugin/src/main/groovy/org/davy/utils/plugin/OnlyCopyTransform.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy similarity index 98% rename from plugin/src/main/groovy/org/davy/utils/plugin/OnlyCopyTransform.groovy rename to plugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy index 28d7476..59d76d8 100644 --- a/plugin/src/main/groovy/org/davy/utils/plugin/OnlyCopyTransform.groovy +++ b/plugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy @@ -1,4 +1,4 @@ -package org.davy.utils.plugin +package org.greenleaf.utils.plugin import com.android.build.api.transform.* import com.android.build.gradle.internal.pipeline.TransformManager diff --git a/samples/src/androidTest/java/org/davy/utils/samples/ExampleInstrumentedTest.java b/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java similarity index 95% rename from samples/src/androidTest/java/org/davy/utils/samples/ExampleInstrumentedTest.java rename to samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java index d601b01..0fa6420 100644 --- a/samples/src/androidTest/java/org/davy/utils/samples/ExampleInstrumentedTest.java +++ b/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java @@ -1,4 +1,4 @@ -package org.davy.utils.samples; +package org.greenleaf.utils.samples; import android.content.Context; import android.support.test.InstrumentationRegistry; diff --git a/samples/src/main/AndroidManifest.xml b/samples/src/main/AndroidManifest.xml index 124e271..edfdd9e 100644 --- a/samples/src/main/AndroidManifest.xml +++ b/samples/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + package="org.greenleaf.utils.samples"> diff --git a/samples/src/main/java/org/davy/utils/samples/MainActivity.java b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java similarity index 96% rename from samples/src/main/java/org/davy/utils/samples/MainActivity.java rename to samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java index f805adc..2af06ec 100644 --- a/samples/src/main/java/org/davy/utils/samples/MainActivity.java +++ b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java @@ -1,4 +1,4 @@ -package org.davy.utils.samples; +package org.greenleaf.utils.samples; import android.content.pm.ActivityInfo; import android.content.pm.PackageInfo; @@ -6,9 +6,9 @@ import android.support.v7.app.AppCompatActivity; import android.widget.Toast; -import org.davy.utils.IOUtils; -import org.davy.utils.NetworkUtil; -import org.davy.utils.XmlUtil; +import org.greenleaf.utils.IOUtils; +import org.greenleaf.utils.NetworkUtil; +import org.greenleaf.utils.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; diff --git a/samples/src/main/res/layout/activity_main.xml b/samples/src/main/res/layout/activity_main.xml index 7c01b8c..5302b61 100644 --- a/samples/src/main/res/layout/activity_main.xml +++ b/samples/src/main/res/layout/activity_main.xml @@ -4,6 +4,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="org.davy.utils.samples.MainActivity"> + tools:context="org.greenleaf.utils.samples.MainActivity"> diff --git a/samples/src/test/java/org/davy/utils/samples/ExampleUnitTest.java b/samples/src/test/java/org/greenleaf/utils/samples/ExampleUnitTest.java similarity index 90% rename from samples/src/test/java/org/davy/utils/samples/ExampleUnitTest.java rename to samples/src/test/java/org/greenleaf/utils/samples/ExampleUnitTest.java index 7a03b21..470a0e1 100644 --- a/samples/src/test/java/org/davy/utils/samples/ExampleUnitTest.java +++ b/samples/src/test/java/org/greenleaf/utils/samples/ExampleUnitTest.java @@ -1,4 +1,4 @@ -package org.davy.utils.samples; +package org.greenleaf.utils.samples; import org.junit.Test; From b02913349563cbb1eae608173ea50f595ac7e59a Mon Sep 17 00:00:00 2001 From: wangyh <1051522865@qq.com> Date: Fri, 8 Jun 2018 01:39:36 +0800 Subject: [PATCH 04/13] update --- build.gradle | 4 ++-- library/bintray.gradle | 0 .../groovy/org/greenleaf/utils/plugin/InjectTransform.groovy | 2 +- .../utils/plugin/{MyInject.groovy => Injecter.groovy} | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 library/bintray.gradle rename plugin/src/main/groovy/org/greenleaf/utils/plugin/{MyInject.groovy => Injecter.groovy} (98%) diff --git a/build.gradle b/build.gradle index 95d0e7d..0b88aff 100644 --- a/build.gradle +++ b/build.gradle @@ -8,8 +8,8 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.1.2' - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' } } diff --git a/library/bintray.gradle b/library/bintray.gradle new file mode 100644 index 0000000..e69de29 diff --git a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy index dd8b8a7..2fe92be 100644 --- a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy +++ b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy @@ -54,7 +54,7 @@ public class InjectTransform extends Transform { //对类型为“文件夹”的input进行遍历 input.directoryInputs.each { DirectoryInput directoryInput -> //文件夹里面包含的是我们手写的类以及R.class、BuildConfig.class以及R$XXX.class等 - MyInject.injectDir(directoryInput.file.absolutePath, "org/davy/commons/samples") + Injecter.injectDir(directoryInput.file.absolutePath, "org/davy/commons/samples") // 获取output目录 def dest = transformInvocation.outputProvider.getContentLocation(directoryInput.name, directoryInput.contentTypes, directoryInput.scopes, diff --git a/plugin/src/main/groovy/org/greenleaf/utils/plugin/MyInject.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy similarity index 98% rename from plugin/src/main/groovy/org/greenleaf/utils/plugin/MyInject.groovy rename to plugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy index 8e4c026..92f93d4 100644 --- a/plugin/src/main/groovy/org/greenleaf/utils/plugin/MyInject.groovy +++ b/plugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy @@ -8,10 +8,10 @@ import javassist.ClassPool import javassist.CtClass import javassist.CtConstructor -public class MyInject { +public class Injecter { private static ClassPool pool = ClassPool.getDefault() - private static String injectStr = "System.out.println(\"inject MyInject\" ); "; + private static String injectStr = "System.out.println(\"inject Injecter\" ); "; public static void injectDir(String path, String packageName) { println(path + " " + packageName) From d602f4f1f96f317a4b4320818603f9496ba0adef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B0=B8=E5=8D=8E?= Date: Fri, 8 Jun 2018 14:20:21 +0800 Subject: [PATCH 05/13] fix --- .idea/checkstyle-idea.xml | 16 + .idea/dbnavigator.xml | 453 ++++++++++++++++++ .idea/kotlinc.xml | 7 + .idea/modules.xml | 4 + build.gradle | 16 +- library/build.gradle | 20 +- plugin/build.gradle | 16 +- .../utils/plugin/InjectPlugin.groovy | 12 +- .../utils/plugin/InjectTransform.groovy | 14 +- .../gradle-plugins/injectplugin.properties | 1 + samples/build.gradle | 5 +- .../greenleaf/utils/samples/MainActivity.java | 3 - samples/src/main/res/layout/activity_main.xml | 5 +- 13 files changed, 541 insertions(+), 31 deletions(-) create mode 100644 .idea/checkstyle-idea.xml create mode 100644 .idea/dbnavigator.xml create mode 100644 .idea/kotlinc.xml create mode 100644 plugin/src/resources/META-INF/gradle-plugins/injectplugin.properties diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml new file mode 100644 index 0000000..b6e4700 --- /dev/null +++ b/.idea/checkstyle-idea.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml new file mode 100644 index 0000000..67ce0f0 --- /dev/null +++ b/.idea/dbnavigator.xml @@ -0,0 +1,453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..548df33 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 02f1ec8..3ce30a0 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,8 +3,12 @@ + + + + diff --git a/build.gradle b/build.gradle index 0b88aff..aba052f 100644 --- a/build.gradle +++ b/build.gradle @@ -6,10 +6,8 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.2' - - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.novoda:bintray-release:0.8.1' } } @@ -22,3 +20,13 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir } + +ext { + userOrg = 'davy' + groupId = 'org.greenleaf.utils' + uploadName = 'greenleaf.utils' + publishVersion = '1.0.0' + desc = 'useful tool for android' + website = 'https://github.com/davyjoneswang/AndroidCommonUtils' + licences = ['Apache-2.0'] +} \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle index 501d903..23895e4 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,10 +1,21 @@ apply plugin: 'com.android.library' +apply plugin: 'com.novoda.bintray-release' + +publish { + artifactId = 'utils' + userOrg = rootProject.ext.userOrg + groupId = rootProject.ext.groupId + uploadName = rootProject.ext.uploadName + publishVersion = rootProject.ext.publishVersion + desc = rootProject.ext.desc + website = rootProject.ext.website + licences = rootProject.ext.licences +} android { compileSdkVersion 25 - defaultConfig { - minSdkVersion 19 + minSdkVersion 17 targetSdkVersion 25 versionCode 1 versionName "1.0" @@ -18,13 +29,14 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + buildToolsVersion '25.0.3' } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) + compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:appcompat-v7:25.4.0' testCompile 'junit:junit:4.12' } diff --git a/plugin/build.gradle b/plugin/build.gradle index faa8e95..af78f00 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -1,8 +1,22 @@ apply plugin: 'groovy' +apply plugin: 'com.novoda.bintray-release' + +publish { + artifactId = 'injectplugin' + userOrg = rootProject.ext.userOrg + groupId = rootProject.ext.groupId + uploadName = rootProject.ext.uploadName + publishVersion = rootProject.ext.publishVersion + desc = rootProject.ext.desc + website = rootProject.ext.website + licences = rootProject.ext.licences +} dependencies { compile gradleApi()//gradle sdk - compile 'com.android.tools.build:gradle:2.3.1' + compile localGroovy() + compile 'com.android.tools.build:gradle:2.3.3' + compile 'org.apache.commons:commons-io:1.3.2' compile 'org.javassist:javassist:3.20.0-GA' } diff --git a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy index 266231b..46075a0 100644 --- a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy +++ b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy @@ -1,4 +1,4 @@ -package org.greenleaf.utils.plugin; +package org.greenleaf.utils.plugin import org.gradle.api.Plugin import org.gradle.api.Project @@ -7,11 +7,11 @@ public class InjectPlugin implements Plugin { @Override void apply(Project project) { - def log = project.logger; - println("========================"); - println("InjectPlugin!"); - println(project.version); - println("========================"); + def log = project.logger + println("========================") + println("InjectPlugin!") + println(project.version) + println("========================") project.android.registerTransform(new OnlyCopyTransform(project)) project.android.registerTransform(new InjectTransform(project)) } diff --git a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy index 2fe92be..d851bf4 100644 --- a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy +++ b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy @@ -12,7 +12,7 @@ import org.gradle.api.Project public class InjectTransform extends Transform { - Project project; + Project project InjectTransform(Project project) { this.project = project @@ -20,22 +20,22 @@ public class InjectTransform extends Transform { @Override String getName() { - return this.class.simpleName; + return this.class.simpleName } @Override Set getInputTypes() { - return TransformManager.CONTENT_CLASS; + return TransformManager.CONTENT_CLASS } @Override Set getOutputTypes() { - return TransformManager.CONTENT_CLASS; + return TransformManager.CONTENT_CLASS } @Override Set getScopes() { - return TransformManager.SCOPE_FULL_PROJECT; + return TransformManager.SCOPE_FULL_PROJECT } @Override @@ -47,7 +47,7 @@ public class InjectTransform extends Transform { void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException { super.transform(transformInvocation) - println this.class.simpleName + "transform start"; + println this.class.simpleName + "transform start" // Transform的inputs有两种类型,一种是目录,一种是jar包,要分开遍历 transformInvocation.inputs.each { TransformInput input -> @@ -87,6 +87,6 @@ public class InjectTransform extends Transform { } } - println this.class.simpleName + " transform end"; + println this.class.simpleName + " transform end" } } diff --git a/plugin/src/resources/META-INF/gradle-plugins/injectplugin.properties b/plugin/src/resources/META-INF/gradle-plugins/injectplugin.properties new file mode 100644 index 0000000..38bdb2e --- /dev/null +++ b/plugin/src/resources/META-INF/gradle-plugins/injectplugin.properties @@ -0,0 +1 @@ +implementation-class = org.greenleaf.utils.plugin.InjectPlugin \ No newline at end of file diff --git a/samples/build.gradle b/samples/build.gradle index 11b1d28..dc865c5 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -2,10 +2,9 @@ apply plugin: 'com.android.application' android { compileSdkVersion 25 - buildToolsVersion "25.0.3" defaultConfig { applicationId "org.davy.commons.samples" - minSdkVersion 19 + minSdkVersion 17 targetSdkVersion 25 versionCode 1 versionName "1.0" @@ -18,6 +17,7 @@ android { } } sourceSets { main { assets.srcDirs = ['src/main/assets', 'src/main/assets/'] } } + buildToolsVersion '25.0.3' } dependencies { @@ -27,6 +27,5 @@ dependencies { }) compile project(':library') compile 'com.android.support:appcompat-v7:25.4.0' - compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' } diff --git a/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java index 2af06ec..4a3011f 100644 --- a/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java +++ b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java @@ -4,10 +4,8 @@ import android.content.pm.PackageInfo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; -import android.widget.Toast; import org.greenleaf.utils.IOUtils; -import org.greenleaf.utils.NetworkUtil; import org.greenleaf.utils.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; @@ -27,7 +25,6 @@ protected void onCreate(Bundle savedInstanceState) { ActivityInfo[] activities = packageInfo.activities; activities[0].getThemeResource(); - Toast.makeText(this, NetworkUtil.getCurrentIp(this), Toast.LENGTH_LONG).show(); InputStream inputStream = null; try { inputStream = getAssets().open("AndroidManifest.xml"); diff --git a/samples/src/main/res/layout/activity_main.xml b/samples/src/main/res/layout/activity_main.xml index 5302b61..9daf193 100644 --- a/samples/src/main/res/layout/activity_main.xml +++ b/samples/src/main/res/layout/activity_main.xml @@ -1,9 +1,8 @@ - - + From 3979669eebc83ad99f1d20127aecfcea61c13dbb Mon Sep 17 00:00:00 2001 From: wangyh <1051522865@qq.com> Date: Sat, 9 Jun 2018 23:11:14 +0800 Subject: [PATCH 06/13] 1.0.1 --- .idea/modules.xml | 4 - build.gradle | 2 +- .../java/org/greenleaf/utils/AppUtils.java | 98 +------------------ .../java/org/greenleaf/utils/AssetsUtils.java | 18 +--- .../java/org/greenleaf/utils/Base64Utils.java | 27 +---- .../java/org/greenleaf/utils/BitmapUtils.java | 6 -- .../org/greenleaf/utils/CollectionUtils.java | 43 +------- .../org/greenleaf/utils/DisplayUtils.java | 31 +----- .../java/org/greenleaf/utils/FileUtils.java | 16 --- .../java/org/greenleaf/utils/IOUtils.java | 16 --- .../java/org/greenleaf/utils/NumberUtils.java | 8 -- .../org/greenleaf/utils/PackageUtils.java | 8 -- .../java/org/greenleaf/utils/RandomUtils.java | 7 +- .../main/java/org/greenleaf/utils/SPUtil.java | 31 ------ .../java/org/greenleaf/utils/SystemUtils.java | 34 +------ .../java/org/greenleaf/utils/ToastUtil.java | 6 +- 16 files changed, 11 insertions(+), 344 deletions(-) diff --git a/.idea/modules.xml b/.idea/modules.xml index 3ce30a0..02f1ec8 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,12 +3,8 @@ - - - - diff --git a/build.gradle b/build.gradle index aba052f..f8fce89 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ ext { userOrg = 'davy' groupId = 'org.greenleaf.utils' uploadName = 'greenleaf.utils' - publishVersion = '1.0.0' + publishVersion = '1.0.1' desc = 'useful tool for android' website = 'https://github.com/davyjoneswang/AndroidCommonUtils' licences = ['Apache-2.0'] diff --git a/library/src/main/java/org/greenleaf/utils/AppUtils.java b/library/src/main/java/org/greenleaf/utils/AppUtils.java index 7a0993b..af054b6 100644 --- a/library/src/main/java/org/greenleaf/utils/AppUtils.java +++ b/library/src/main/java/org/greenleaf/utils/AppUtils.java @@ -10,25 +10,8 @@ import java.util.List; -import javax.security.auth.x500.X500Principal; - -/** - * @author: wlj - * @Date: 2017-03-28 - * @email: wanglijundev@gmail.com - * @desc: App 相关信息,包括版本名称、版本号、包名等等 - */ - public class AppUtils { - private final static X500Principal DEBUG_DN = new X500Principal( - "CN=Android Debug,O=Android,C=US"); - - /** - * Get version name - * - * @param context - * @return - */ + public static String getVersionName(Context context) { PackageInfo info; try { @@ -40,12 +23,6 @@ public static String getVersionName(Context context) { return ""; } - /** - * Get version code - * - * @param context - * @return - */ public static int getVersionCode(Context context) { PackageInfo info; try { @@ -57,33 +34,14 @@ public static int getVersionCode(Context context) { return 0; } - /** - * Get package name - * - * @param context - * @return - */ public static String getPackageName(Context context) { return context.getPackageName(); } - /** - * Get icon - * - * @param context - * @return - */ public static Drawable getIcon(Context context) { return getAppIcon(context, getPackageName(context)); } - /** - * Get app icon - * - * @param context - * @param packageName - * @return - */ public static Drawable getAppIcon(Context context, String packageName) { try { PackageManager pm = context.getPackageManager(); @@ -95,13 +53,6 @@ public static Drawable getAppIcon(Context context, String packageName) { return null; } - /** - * Get app version name - * - * @param context - * @param packageName - * @return - */ public static String getAppVersionName(Context context, String packageName) { try { PackageManager pm = context.getPackageManager(); @@ -113,13 +64,6 @@ public static String getAppVersionName(Context context, String packageName) { return null; } - /** - * Get app version code - * - * @param context - * @param packageName - * @return - */ public static int getAppVersionCode(Context context, String packageName) { try { PackageManager pm = context.getPackageManager(); @@ -131,13 +75,6 @@ public static int getAppVersionCode(Context context, String packageName) { return -1; } - /** - * Get app name - * - * @param context - * @param packageName - * @return - */ public static String getAppName(Context context, String packageName) { try { PackageManager pm = context.getPackageManager(); @@ -149,13 +86,6 @@ public static String getAppName(Context context, String packageName) { return null; } - /** - * Get app permission - * - * @param context - * @param packageName - * @return - */ public static String[] getAppPermission(Context context, String packageName) { try { PackageManager pm = context.getPackageManager(); @@ -167,13 +97,6 @@ public static String[] getAppPermission(Context context, String packageName) { return null; } - /** - * Get app signature - * - * @param context - * @param packageName - * @return - */ public static String getAppSignature(Context context, String packageName) { try { PackageManager pm = context.getPackageManager(); @@ -185,12 +108,6 @@ public static String getAppSignature(Context context, String packageName) { return null; } - /** - * Judge whether an app is dubuggable - * - * @param context - * @return - */ public static boolean isApkDebuggable(Context context) { try { ApplicationInfo info = context.getApplicationInfo(); @@ -201,13 +118,6 @@ public static boolean isApkDebuggable(Context context) { return false; } - /** - * Judge whether an app is dubuggable by package name - * - * @param context - * @param packageName - * @return - */ public static boolean isApkDebugable(Context context, String packageName) { try { PackageInfo pkginfo = context.getPackageManager().getPackageInfo( @@ -221,12 +131,6 @@ public static boolean isApkDebugable(Context context, String packageName) { return false; } - /** - * Judge whether an app is in background - * - * @param context - * @return - */ public static boolean isAppInBackground(Context context) { ActivityManager am = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); diff --git a/library/src/main/java/org/greenleaf/utils/AssetsUtils.java b/library/src/main/java/org/greenleaf/utils/AssetsUtils.java index 4c6195b..b02141b 100644 --- a/library/src/main/java/org/greenleaf/utils/AssetsUtils.java +++ b/library/src/main/java/org/greenleaf/utils/AssetsUtils.java @@ -14,32 +14,16 @@ import java.io.InputStreamReader; /** - * @desc: Assets操作 + * Assets操作 */ - public class AssetsUtils { private static final String ENCODING = "UTF-8"; - /** - * 从assets获取文件 - * - * @param context - * @param fileName - * @return - * @throws IOException - */ public static InputStream getFileFromAssets(@NonNull Context context, String fileName) throws IOException { AssetManager am = context.getAssets(); return am.open(fileName); } - /** - * 从assets获取文本文件 - * - * @param context - * @param fileName - * @return - */ @WorkerThread public static String asset2String(@NonNull Context context, String fileName) { diff --git a/library/src/main/java/org/greenleaf/utils/Base64Utils.java b/library/src/main/java/org/greenleaf/utils/Base64Utils.java index 7efc6e7..b3e8d02 100644 --- a/library/src/main/java/org/greenleaf/utils/Base64Utils.java +++ b/library/src/main/java/org/greenleaf/utils/Base64Utils.java @@ -3,46 +3,23 @@ import android.util.Base64; /** - * @desc: bese64的转换 + * bese64的转换 */ public class Base64Utils { - /** - * base64编码 - * - * @param input - * @return - */ + public static byte[] encode(byte[] input) { return Base64.encode(input, Base64.DEFAULT); } - /** - * base64编码 - * - * @param s - * @return - */ public static String encode(String s) { return Base64.encodeToString(s.getBytes(), Base64.DEFAULT); } - /** - * base64解码 - * - * @param input - * @return - */ public static byte[] decode(byte[] input) { return Base64.decode(input, Base64.DEFAULT); } - /** - * base64解码 - * - * @param s - * @return - */ public static String decode(String s) { return new String(Base64.decode(s, Base64.DEFAULT)); } diff --git a/library/src/main/java/org/greenleaf/utils/BitmapUtils.java b/library/src/main/java/org/greenleaf/utils/BitmapUtils.java index 68ba12f..a3bc6ef 100644 --- a/library/src/main/java/org/greenleaf/utils/BitmapUtils.java +++ b/library/src/main/java/org/greenleaf/utils/BitmapUtils.java @@ -20,12 +20,6 @@ public static Bitmap convertViewToBitmap(View view, int width, int height) { return bitmap; } - /** - * Convert view to bitmap - * - * @param view - * @return - */ public static Bitmap convertViewToBitmap(View view) { return convertViewToBitmap(view, UNSPECIFIED, UNSPECIFIED); } diff --git a/library/src/main/java/org/greenleaf/utils/CollectionUtils.java b/library/src/main/java/org/greenleaf/utils/CollectionUtils.java index ef84231..a08ad51 100644 --- a/library/src/main/java/org/greenleaf/utils/CollectionUtils.java +++ b/library/src/main/java/org/greenleaf/utils/CollectionUtils.java @@ -11,74 +11,33 @@ /** * 集合工具类 */ - public class CollectionUtils { private static final String DELIMITER = ","; - /** - * 判断集合是否为空 - * - * @param c - * @param - * @return - */ public static boolean isEmpty(Collection c) { return (c == null || c.isEmpty()); } - /** - * 判断集合是否不为空 - * - * @param c - * @param - * @return - */ public static boolean isNotEmpty(Collection c) { return !isEmpty(c); } - /** - * Join collection to string, separator is {@link #DELIMITER} - * - * @param tokens - * @return - */ + public static String join(Iterable tokens) { return tokens == null ? "" : TextUtils.join(DELIMITER, tokens); } - /** - * 将数组转为list - * - * @param array - * @param - * @return - */ public static List asList(T... array) { return Arrays.asList(array); } - /** - * 将数组转为set集合 - * - * @param array - * @param - * @return - */ public static Set asSet(T... array) { return new HashSet(asList(array)); } - /** - * 集合转为数组 - * - * @param c - * @return - */ public static Object[] asArray(Collection c) { if (!isEmpty(c)) { return c.toArray(); } return null; } - } diff --git a/library/src/main/java/org/greenleaf/utils/DisplayUtils.java b/library/src/main/java/org/greenleaf/utils/DisplayUtils.java index bb43405..f0524e2 100644 --- a/library/src/main/java/org/greenleaf/utils/DisplayUtils.java +++ b/library/src/main/java/org/greenleaf/utils/DisplayUtils.java @@ -7,56 +7,27 @@ import android.util.DisplayMetrics; public class DisplayUtils { - /** - * Get screen width, in pixels - * - * @param context - * @return - */ + public static int getScreenWidth(Context context) { DisplayMetrics dm = context.getResources().getDisplayMetrics(); return dm.widthPixels; } - /** - * Get screen height, in pixels - * - * @param context - * @return - */ public static int getScreenHeight(Context context) { DisplayMetrics dm = context.getResources().getDisplayMetrics(); return dm.heightPixels; } - /** - * Get screen density, the logical density of the display - * - * @param context - * @return - */ public static float getScreenDensity(Context context) { DisplayMetrics dm = context.getResources().getDisplayMetrics(); return dm.density; } - /** - * Get screen density dpi, the screen density expressed as dots-per-inch - * - * @param context - * @return - */ public static int getScreenDensityDPI(Context context) { DisplayMetrics dm = context.getResources().getDisplayMetrics(); return dm.densityDpi; } - /** - * Get statusbar height - * - * @param activity - * @return - */ public static int getStatusBarHeight(@NonNull Activity activity) { Rect rect = new Rect(); activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); diff --git a/library/src/main/java/org/greenleaf/utils/FileUtils.java b/library/src/main/java/org/greenleaf/utils/FileUtils.java index a48d0cd..abb6cf3 100644 --- a/library/src/main/java/org/greenleaf/utils/FileUtils.java +++ b/library/src/main/java/org/greenleaf/utils/FileUtils.java @@ -1,19 +1,3 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package org.greenleaf.utils; import java.io.File; diff --git a/library/src/main/java/org/greenleaf/utils/IOUtils.java b/library/src/main/java/org/greenleaf/utils/IOUtils.java index 53db4de..f27cd74 100644 --- a/library/src/main/java/org/greenleaf/utils/IOUtils.java +++ b/library/src/main/java/org/greenleaf/utils/IOUtils.java @@ -1,19 +1,3 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package org.greenleaf.utils; import java.io.Closeable; diff --git a/library/src/main/java/org/greenleaf/utils/NumberUtils.java b/library/src/main/java/org/greenleaf/utils/NumberUtils.java index 03a1281..b6eac4f 100644 --- a/library/src/main/java/org/greenleaf/utils/NumberUtils.java +++ b/library/src/main/java/org/greenleaf/utils/NumberUtils.java @@ -2,14 +2,6 @@ import java.text.DecimalFormat; -/** - * @author wlj - * @date 2017/3/29 - * @email wanglijundev@gmail.com - * @packagename wanglijun.vip.androidutils.utils - * @desc: 数字格式化操作类 - */ - public class NumberUtils { private static final DecimalFormat oneDec = new DecimalFormat("##0.0"); diff --git a/library/src/main/java/org/greenleaf/utils/PackageUtils.java b/library/src/main/java/org/greenleaf/utils/PackageUtils.java index 838b56e..78ff4d5 100644 --- a/library/src/main/java/org/greenleaf/utils/PackageUtils.java +++ b/library/src/main/java/org/greenleaf/utils/PackageUtils.java @@ -14,14 +14,6 @@ import java.util.ArrayList; import java.util.List; -/** - * @author wlj - * @date 2017/3/29 - * @email wanglijundev@gmail.com - * @packagename wanglijun.vip.androidutils.utils - * @desc: 包的相关操作 - */ - public class PackageUtils { public static boolean checkPermission(@NonNull Context context, String permName, String pkgName) { diff --git a/library/src/main/java/org/greenleaf/utils/RandomUtils.java b/library/src/main/java/org/greenleaf/utils/RandomUtils.java index 896ad6b..92c2120 100644 --- a/library/src/main/java/org/greenleaf/utils/RandomUtils.java +++ b/library/src/main/java/org/greenleaf/utils/RandomUtils.java @@ -7,12 +7,7 @@ */ public class RandomUtils { - /** - * Returns a pseudo-random uniformly distributed {@code int}. - * 返回伪随机均匀分布 - * - * @return - */ + public static int randomInt() { Random random = new Random(); return random.nextInt(); diff --git a/library/src/main/java/org/greenleaf/utils/SPUtil.java b/library/src/main/java/org/greenleaf/utils/SPUtil.java index 12cda3e..bc31a3c 100644 --- a/library/src/main/java/org/greenleaf/utils/SPUtil.java +++ b/library/src/main/java/org/greenleaf/utils/SPUtil.java @@ -10,13 +10,6 @@ public class SPUtil { public static final String FILE_NAME = "share_data"; - /** - * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法 - * - * @param context - * @param key - * @param object - */ public static void put(@NonNull Context context, String key, Object object) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, @@ -39,15 +32,6 @@ public static void put(@NonNull Context context, String key, Object object) { editor.apply(); } - - /** - * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值 - * - * @param context - * @param key - * @param defaultObject - * @return - */ public static Object get(Context context, String key, Object defaultObject) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); @@ -66,12 +50,6 @@ public static Object get(Context context, String key, Object defaultObject) { return null; } - /** - * 移除某个key值已经对应的值 - * - * @param context - * @param key - */ public static void remove(Context context, String key) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); @@ -81,8 +59,6 @@ public static void remove(Context context, String key) { /** * 清除所有数据 - * - * @param context */ public static void clear(Context context) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, @@ -93,10 +69,6 @@ public static void clear(Context context) { /** * 查询某个key是否已经存在 - * - * @param context - * @param key - * @return */ public static boolean contains(Context context, String key) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, @@ -106,9 +78,6 @@ public static boolean contains(Context context, String key) { /** * 返回所有的键值对 - * - * @param context - * @return */ public static Map getAll(Context context) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, diff --git a/library/src/main/java/org/greenleaf/utils/SystemUtils.java b/library/src/main/java/org/greenleaf/utils/SystemUtils.java index 1463f73..1da31dc 100644 --- a/library/src/main/java/org/greenleaf/utils/SystemUtils.java +++ b/library/src/main/java/org/greenleaf/utils/SystemUtils.java @@ -9,8 +9,6 @@ public class SystemUtils { /** * ART - * - * @return */ public static boolean isART() { final String vmVersion = System.getProperty("java.vm.version"); @@ -19,8 +17,6 @@ public static boolean isART() { /** * DALVIK - * - * @return */ public static boolean isDalvik() { final String vmVersion = System.getProperty("java.vm.version"); @@ -28,18 +24,14 @@ public static boolean isDalvik() { } /** - * The brand (e.g., Xiaomi) the software is customized for, if any. - * - * @return + * The brand */ public static String getBrand() { return Build.BRAND; } /** - * The name of the underlying board, like "MSM8660_SURF". - * - * @return + * The board */ public static String getBoard() { return Build.BOARD; @@ -47,8 +39,6 @@ public static String getBoard() { /** * The end-user-visible name for the end product, like "MI-ONE Plus". - * - * @return */ public static String getModel() { return Build.MODEL; @@ -56,8 +46,6 @@ public static String getModel() { /** * Either a changelist number, or a label like "JZO54K". - * - * @return */ public static String getID() { return Build.ID; @@ -65,8 +53,6 @@ public static String getID() { /** * The user-visible version string, like "4.1.2". - * - * @return */ public static String getVersionRelease() { return Build.VERSION.RELEASE; @@ -74,8 +60,6 @@ public static String getVersionRelease() { /** * The user-visible SDK version of the framework. - * - * @return */ public static int getVersionSDK() { return Build.VERSION.SDK_INT; @@ -83,8 +67,6 @@ public static int getVersionSDK() { /** * A string that uniquely identifies this build. Do not attempt to parse this value. - * - * @return */ public static String getFingerPrint() { return Build.FINGERPRINT; @@ -92,8 +74,6 @@ public static String getFingerPrint() { /** * The name of the overall product, like "mione_plus". - * - * @return */ public static String getProduct() { return Build.PRODUCT; @@ -101,8 +81,6 @@ public static String getProduct() { /** * The manufacturer of the product/hardware, like "Xiaomi". - * - * @return */ public static String getManufacturer() { return Build.MANUFACTURER; @@ -110,8 +88,6 @@ public static String getManufacturer() { /** * The name of the industrial design, like "mione_plus". - * - * @return */ public static String getDevice() { return Build.DEVICE; @@ -119,8 +95,6 @@ public static String getDevice() { /** * The name of the instruction set (CPU type + ABI convention) of native code, like "armeabi-v7a". - * - * @return */ public static String getCpuAbi() { return Build.CPU_ABI; @@ -128,8 +102,6 @@ public static String getCpuAbi() { /** * The name of the second instruction set (CPU type + ABI convention) of native code, like "armeabi". - * - * @return */ public static String getCpuAbi2() { return Build.CPU_ABI2; @@ -137,8 +109,6 @@ public static String getCpuAbi2() { /** * A build ID string meant for displaying to the user, like "JZO54K". - * - * @return */ public static String getDisplay() { return Build.DISPLAY; diff --git a/library/src/main/java/org/greenleaf/utils/ToastUtil.java b/library/src/main/java/org/greenleaf/utils/ToastUtil.java index 0232a0c..db06b64 100644 --- a/library/src/main/java/org/greenleaf/utils/ToastUtil.java +++ b/library/src/main/java/org/greenleaf/utils/ToastUtil.java @@ -6,11 +6,7 @@ import android.widget.Toast; /** - * @author wlj - * @date 2017/3/28 - * @email wanglijundev@gmail.com - * @packagename wanglijun.vip.androidutils - * @description Toast封装类 + * Toast封装类 */ public class ToastUtil { From 13c5012e400bc62d45575fdeff909970970adefe Mon Sep 17 00:00:00 2001 From: wangyh <1051522865@qq.com> Date: Sun, 10 Jun 2018 13:45:09 +0800 Subject: [PATCH 07/13] update --- library/bintray.gradle | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 library/bintray.gradle diff --git a/library/bintray.gradle b/library/bintray.gradle deleted file mode 100644 index e69de29..0000000 From f0a83a864bbf2352c51074a0f5c4818ce468d9d6 Mon Sep 17 00:00:00 2001 From: wangyh <1051522865@qq.com> Date: Sun, 10 Jun 2018 23:56:03 +0800 Subject: [PATCH 08/13] seuc --- .idea/caches/build_file_checksums.ser | Bin 642 -> 648 bytes .idea/gradle.xml | 2 +- .idea/modules.xml | 2 +- build.gradle | 10 +- {plugin => injectplugin}/.gitignore | 0 {plugin => injectplugin}/build.gradle | 18 ++- .../utils/plugin/InjectExtension.groovy | 18 +++ .../utils/plugin/InjectPlugin.groovy | 30 ++++ .../utils/plugin/InjectTransform.groovy | 29 ++-- .../greenleaf/utils/plugin/Injecter.groovy | 138 ++++++++++++++++++ .../greenleaf/utils/plugin/JarZipUtil.groovy | 70 +++++++++ .../utils/plugin/OnlyCopyTransform.groovy | 17 +-- ...rg.greenleaf.utils.injectplugin.properties | 0 library/build.gradle | 29 +++- .../utils/plugin/InjectPlugin.groovy | 18 --- .../greenleaf/utils/plugin/Injecter.groovy | 60 -------- .../injectplugin/1.0.0/injectplugin-1.0.0.jar | Bin 0 -> 37722 bytes .../1.0.0/injectplugin-1.0.0.jar.md5 | 1 + .../1.0.0/injectplugin-1.0.0.jar.sha1 | 1 + .../injectplugin/1.0.0/injectplugin-1.0.0.pom | 28 ++++ .../1.0.0/injectplugin-1.0.0.pom.md5 | 1 + .../1.0.0/injectplugin-1.0.0.pom.sha1 | 1 + .../utils/injectplugin/maven-metadata.xml | 12 ++ .../utils/injectplugin/maven-metadata.xml.md5 | 1 + .../injectplugin/maven-metadata.xml.sha1 | 1 + samples/build.gradle | 36 ++++- .../src/main/java/com/google/utils/Utils.java | 4 + .../utils/samples/InjectedClsss.java | 7 + .../greenleaf/utils/samples/MainActivity.java | 113 +------------- settings.gradle | 2 +- 30 files changed, 421 insertions(+), 228 deletions(-) rename {plugin => injectplugin}/.gitignore (100%) rename {plugin => injectplugin}/build.gradle (58%) create mode 100644 injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectExtension.groovy create mode 100644 injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy rename {plugin => injectplugin}/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy (75%) create mode 100644 injectplugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy create mode 100644 injectplugin/src/main/groovy/org/greenleaf/utils/plugin/JarZipUtil.groovy rename {plugin => injectplugin}/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy (89%) rename plugin/src/resources/META-INF/gradle-plugins/injectplugin.properties => injectplugin/src/main/resources/META-INF/gradle-plugins/org.greenleaf.utils.injectplugin.properties (100%) delete mode 100644 plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy delete mode 100644 plugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy create mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar create mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar.md5 create mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar.sha1 create mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom create mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.md5 create mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.sha1 create mode 100644 repo/org/greenleaf/utils/injectplugin/maven-metadata.xml create mode 100644 repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.md5 create mode 100644 repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.sha1 create mode 100644 samples/src/main/java/com/google/utils/Utils.java create mode 100644 samples/src/main/java/org/greenleaf/utils/samples/InjectedClsss.java diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 32aa9b4c4a9670dd71e3c940cee56a0bda7fdb5b..a64132d8902563e2483676955cbdf64f89414da4 100644 GIT binary patch delta 235 zcmZo-?O>fSgXLB3RNIMj{5koHQ%g!R^U{ka{*bHpQ`qkL#`j3)zEftGd0LlOmoP|X z=4GWOmlWibrf25qCzWRAr0As=C8p%0mKHM9F|aW(FbKSF`tSM@ z29e^#+=86cVjLO{+I_J3Vy!a&D1Y&q-*-*BN*H*+CM#kXZQ+zHKKavHx9^jSB!fAv z8YZt{^b^>rm)&vb*K@Hy4AcBSo<5m1nTyF%z+q~fV0D6k(Z7kjA1*UY-Y_|sNgn`@ CD_gh# delta 257 zcmeBRZDO4;gXOl@0ojRj{Og4aa!S)P^YoKSGjme((u)#Pa#Bl+7?`4+)_fNK!Nw8t zfQf;jqJV*cL11OD@CV+*vv=Q>pZ;mxZ;g{B4E)8ZB_)}8>BTUOg$#8JY#_C9J5E2m zymK9c*a3H!fBo!QB@80PiMa(isl})^O)g;Mv@HE#i_& a&5Ja@Ac!m>2EoaCOwyCfnFImHp=Hwm diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 2e808fd..a5500aa 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -8,8 +8,8 @@ diff --git a/.idea/modules.xml b/.idea/modules.xml index 02f1ec8..e6802ff 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,8 +3,8 @@ + - diff --git a/build.gradle b/build.gradle index f8fce89..ff3af3e 100644 --- a/build.gradle +++ b/build.gradle @@ -4,16 +4,21 @@ buildscript { repositories { jcenter() google() + maven{ + url uri('./repo') + } } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' classpath 'com.novoda:bintray-release:0.8.1' + classpath 'org.greenleaf.utils:injectplugin:1.0.0' } } allprojects { repositories { jcenter() + google() } } @@ -23,9 +28,10 @@ task clean(type: Delete) { ext { userOrg = 'davy' + repoName = "maven" groupId = 'org.greenleaf.utils' - uploadName = 'greenleaf.utils' - publishVersion = '1.0.1' + uploadName = 'AndroidInjectPlugin' + publishVersion = '1.0.0' desc = 'useful tool for android' website = 'https://github.com/davyjoneswang/AndroidCommonUtils' licences = ['Apache-2.0'] diff --git a/plugin/.gitignore b/injectplugin/.gitignore similarity index 100% rename from plugin/.gitignore rename to injectplugin/.gitignore diff --git a/plugin/build.gradle b/injectplugin/build.gradle similarity index 58% rename from plugin/build.gradle rename to injectplugin/build.gradle index af78f00..783e50c 100644 --- a/plugin/build.gradle +++ b/injectplugin/build.gradle @@ -1,15 +1,19 @@ apply plugin: 'groovy' apply plugin: 'com.novoda.bintray-release' +apply plugin: 'maven' publish { artifactId = 'injectplugin' userOrg = rootProject.ext.userOrg + repoName = rootProject.ext.repoName groupId = rootProject.ext.groupId uploadName = rootProject.ext.uploadName publishVersion = rootProject.ext.publishVersion desc = rootProject.ext.desc website = rootProject.ext.website licences = rootProject.ext.licences + bintrayUser = BINTRAY_USER + bintrayKey = BINTRAY_KEY } dependencies { @@ -20,6 +24,16 @@ dependencies { compile 'org.javassist:javassist:3.20.0-GA' } -repositories { - jcenter() + +//设置maven deployer +uploadArchives { + repositories { + mavenDeployer { + pom.artifactId = 'injectplugin' + pom.groupId = 'org.greenleaf.utils' + pom.version = '1.0.0' + //文件发布到下面目录 + repository(url: uri('../repo')) + } + } } \ No newline at end of file diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectExtension.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectExtension.groovy new file mode 100644 index 0000000..147b121 --- /dev/null +++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectExtension.groovy @@ -0,0 +1,18 @@ +package org.greenleaf.utils.plugin + +/** + * Created by davy on 2017/6/8. + */ +public class InjectExtension { + + List injectPackages + String message + + @Override + public String toString() { + return "InjectExtension{" + + "injectPackages=" + injectPackages + + ", message='" + message + '\'' + + '}' + } +} \ No newline at end of file diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy new file mode 100644 index 0000000..e629884 --- /dev/null +++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy @@ -0,0 +1,30 @@ +package org.greenleaf.utils.plugin + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +public class InjectPlugin implements Plugin { + + Logger mLogger = LoggerFactory.getLogger(Injecter.class) + + @Override + void apply(Project project) { + + mLogger.info("========================") + mLogger.info("InjectPlugin") + mLogger.info("========================") + + def injectExtension = project.extensions.create('injectplugin', InjectExtension) + println(injectExtension) //这里返回空,afterEvaluate才能获得值 + + project.afterEvaluate { + println(injectExtension) + } + + project.android.registerTransform(new OnlyCopyTransform(project)) + project.android.registerTransform(new InjectTransform(project, injectExtension)) + + } +} \ No newline at end of file diff --git a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy similarity index 75% rename from plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy rename to injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy index d851bf4..cf2042d 100644 --- a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy +++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy @@ -5,6 +5,8 @@ import com.android.build.gradle.internal.pipeline.TransformManager import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils import org.gradle.api.Project +import org.slf4j.Logger +import org.slf4j.LoggerFactory /** * Created by davy on 2017/6/8. @@ -12,10 +14,14 @@ import org.gradle.api.Project public class InjectTransform extends Transform { + Logger mLogger = LoggerFactory.getLogger(Injecter.class) + Project project + InjectExtension injectExtension - InjectTransform(Project project) { + InjectTransform(Project project, InjectExtension injectExtension) { this.project = project + this.injectExtension = injectExtension } @Override @@ -47,29 +53,32 @@ public class InjectTransform extends Transform { void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException { super.transform(transformInvocation) - println this.class.simpleName + "transform start" + println this.class.simpleName + " transform start." + mLogger.info("{} transform start. ", this.class.simpleName) // Transform的inputs有两种类型,一种是目录,一种是jar包,要分开遍历 transformInvocation.inputs.each { TransformInput input -> //对类型为“文件夹”的input进行遍历 input.directoryInputs.each { DirectoryInput directoryInput -> + //文件夹里面包含的是我们手写的类以及R.class、BuildConfig.class以及R$XXX.class等 - Injecter.injectDir(directoryInput.file.absolutePath, "org/davy/commons/samples") + List stringList = new ArrayList<>() + stringList.addAll(injectExtension.injectPackages) + println "inject path: " + stringList.toString() + + Injecter.injectDir(project, directoryInput.file.absolutePath, stringList) + // 获取output目录 def dest = transformInvocation.outputProvider.getContentLocation(directoryInput.name, directoryInput.contentTypes, directoryInput.scopes, Format.DIRECTORY) - - println "Directory:" + directoryInput.name + " " + directoryInput.contentTypes + " " + directoryInput.file.getAbsolutePath() - println " Output:" + dest.getAbsolutePath() // 将input的目录复制到output指定目录 FileUtils.copyDirectory(directoryInput.file, dest) } //对类型为jar文件的input进行遍历 input.jarInputs.each { JarInput jarInput -> - //jar文件一般是第三方依赖库jar文件 - // 重命名输出文件(同目录copyFile会冲突) + //jar文件一般是第三方依赖库jar文件 重命名输出文件(同目录copyFile会冲突) def jarName = jarInput.name def md5Name = DigestUtils.md5Hex(jarInput.file.getAbsolutePath()) @@ -80,13 +89,11 @@ public class InjectTransform extends Transform { def dest = transformInvocation.outputProvider.getContentLocation(jarName + md5Name, jarInput.contentTypes, jarInput.scopes, Format.JAR) //将输入内容复制到输出 - - println "JAR:" + jarName + " " + jarInput.contentTypes + " " + jarInput.file.getAbsolutePath() + " " + md5Name - println " Output:" + dest.getAbsolutePath() FileUtils.copyFile(jarInput.file, dest) } } println this.class.simpleName + " transform end" + mLogger.info("{} transform end. ", this.class.simpleName) } } diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy new file mode 100644 index 0000000..2cadfc6 --- /dev/null +++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy @@ -0,0 +1,138 @@ +package org.greenleaf.utils.plugin + +import groovy.io.FileType +import javassist.ClassPool +import javassist.CtClass +import javassist.CtConstructor +import org.apache.commons.io.FileUtils +import org.gradle.api.Project + +/** + * Created by davy on 2017/6/8. + */ +public class Injecter { + + private static final ClassPool mPool = ClassPool.getDefault() + private static + final String injectStr = "System.out.println(\"Injecter Helper\");" + + public static void injectDir(final Project project, final String rootPath, final List injectPackages) { + + println "injectDir path:" + rootPath + " injectPackages:" + injectPackages + println project.android.bootClasspath[0].toString() + + mPool.appendClassPath(project.android.bootClasspath[0].toString()) + mPool.appendClassPath(rootPath) + + File dir = new File(rootPath) + if (!dir.isDirectory()) { + return + } + + final Set injectPackagesPathSet = new HashSet<>() + for (String packageNameItem : injectPackages) { + injectPackagesPathSet.add(packageNameItem.replace(".", File.separator)) + } + println injectPackagesPathSet + + dir.eachFileRecurse(FileType.FILES, { File file -> + + println() + println("each file") + String classFilePath = file.absolutePath + String subClassFilePath = classFilePath.substring(rootPath.length() + 1) + println subClassFilePath + + //确保当前文件是class文件,并且不是系统自动生成的class文件 + if (classFilePath.endsWith(".class") + && !classFilePath.contains('R$') + && !classFilePath.contains('R.class') + && !classFilePath.contains("BuildConfig.class")) { + + boolean needInject = false + + int index = -1 + + for (String packageNameItem : injectPackagesPathSet) { + index = subClassFilePath.lastIndexOf(packageNameItem) + println packageNameItem + println subClassFilePath + println index + needInject = index != -1 + if (needInject) { + break + } + } + + println "injectDir process File fileName:" + file.getName() + " inject:" + needInject + + if (needInject) { + + //subClassFilePath .aa.bb.cc.class + int end = subClassFilePath.length() - 6 // .class = 6 + String className = subClassFilePath.substring(index, end) + .replace('\\', '.').replace('/', '.') + + println "injectDir do inject className:" + className + + //开始修改class文件 + CtClass c = mPool.getCtClass(className) + + if (c.isFrozen()) { + c.defrost() + } + + CtConstructor[] cts = c.getDeclaredConstructors() + if (cts == null || cts.length == 0) { + //手动创建一个构造函数 + CtConstructor constructor = new CtConstructor(new CtClass[0], c) + constructor.insertBeforeBody(injectStr) + c.addConstructor(constructor) + } else { + cts[0].insertBeforeBody(injectStr) + } + c.writeFile(rootPath) + c.detach() + } + } + } + ) + } + + /** + * 这里需要将jar包先解压,注入代码后再重新生成jar包 + * @path jar包的绝对路径 + */ + public static void injectJar(String path) { + if (path.endsWith(".jar")) { + File jarFile = new File(path) + + // jar包解压后的保存路径 + String jarZipDir = jarFile.getParent() + "/" + jarFile.getName().replace('.jar', '') + + // 解压jar包, 返回jar包中所有class的完整类名的集合(带.class后缀) + List classNameList = JarZipUtil.unzipJar(path, jarZipDir) + + // 删除原来的jar包 + jarFile.delete() + + // 注入代码 + mPool.appendClassPath(jarZipDir) + for (String className : classNameList) { + if (className.endsWith(".class") + && !className.contains('R$') + && !className.contains('R.class') + && !className.contains("BuildConfig.class")) { + className = className.substring(0, className.length() - 6) + injectClass(className, jarZipDir) + } + } + + // 从新打包jar + JarZipUtil.zipJar(jarZipDir, path) + + // 删除目录 + FileUtils.deleteDirectory(new File(jarZipDir)) + } + } +} \ No newline at end of file diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/JarZipUtil.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/JarZipUtil.groovy new file mode 100644 index 0000000..f51f6e1 --- /dev/null +++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/JarZipUtil.groovy @@ -0,0 +1,70 @@ +package org.greenleaf.utils.plugin + +import java.util.jar.JarEntry +import java.util.jar.JarFile +import java.util.jar.JarOutputStream +import java.util.zip.ZipEntry + +public class JarZipUtil { + + /** + * 将该jar包解压到指定目录 + * + * @param jarPath jar包的绝对路径 + * @param destDirPath jar包解压后的保存路径 + * @return 返回该jar包中包含的所有class的完整类名类名集合,其中一条数据如:com.aitski.hotpatch.Xxxx.class + */ + public static List unzipJar(String jarPath, String destDirPath) { + + List list = new ArrayList() + if (jarPath.endsWith('.jar')) { + + JarFile jarFile = new JarFile(jarPath) + Enumeration jarEntrys = jarFile.entries() + while (jarEntrys.hasMoreElements()) { + JarEntry jarEntry = jarEntrys.nextElement() + if (jarEntry.directory) { + continue + } + String entryName = jarEntry.getName() + if (entryName.endsWith('.class')) { + String className = entryName.replace('\\', '.').replace('/', '.') + list.add(className) + } + String outFileName = destDirPath + "/" + entryName + File outFile = new File(outFileName) + outFile.getParentFile().mkdirs() + InputStream inputStream = jarFile.getInputStream(jarEntry) + FileOutputStream fileOutputStream = new FileOutputStream(outFile) + fileOutputStream << inputStream + fileOutputStream.close() + inputStream.close() + } + jarFile.close() + } + return list + } + + /** + * 重新打包jar + * + * @param packagePath 将这个目录下的所有文件打包成jar + * @param destPath 打包好的jar包的绝对路径 + */ + public static void zipJar(String packagePath, String destPath) { + + File file = new File(packagePath) + JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(destPath)) + file.eachFileRecurse { + File f -> + String entryName = f.getAbsolutePath().substring(packagePath.length() + 1) + outputStream.putNextEntry(new ZipEntry(entryName)) + if (!f.directory) { + InputStream inputStream = new FileInputStream(f) + outputStream << inputStream + inputStream.close() + } + } + outputStream.close() + } +} \ No newline at end of file diff --git a/plugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy similarity index 89% rename from plugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy rename to injectplugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy index 59d76d8..4999e88 100644 --- a/plugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy +++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy @@ -5,16 +5,13 @@ import com.android.build.gradle.internal.pipeline.TransformManager import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils import org.gradle.api.Project - -import java.util.function.Consumer - /** * Created by davy on 2017/6/8. */ public class OnlyCopyTransform extends Transform { - Project project; + Project project OnlyCopyTransform(Project project) { this.project = project @@ -22,22 +19,22 @@ public class OnlyCopyTransform extends Transform { @Override String getName() { - return this.class.simpleName; + return this.class.simpleName } @Override Set getInputTypes() { - return TransformManager.CONTENT_CLASS; + return TransformManager.CONTENT_CLASS } @Override Set getOutputTypes() { - return TransformManager.CONTENT_CLASS; + return TransformManager.CONTENT_CLASS } @Override Set getScopes() { - return TransformManager.SCOPE_FULL_PROJECT; + return TransformManager.SCOPE_FULL_PROJECT } @Override @@ -48,7 +45,7 @@ public class OnlyCopyTransform extends Transform { @Override void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException { super.transform(transformInvocation) - println this.class.simpleName + " transform start"; + println this.class.simpleName + " transform start" // Transform的inputs有两种类型,一种是目录,一种是jar包,要分开遍历 transformInvocation.inputs.each { TransformInput input -> @@ -87,6 +84,6 @@ public class OnlyCopyTransform extends Transform { } } - println this.class.simpleName + " transform end"; + println this.class.simpleName + " transform end" } } diff --git a/plugin/src/resources/META-INF/gradle-plugins/injectplugin.properties b/injectplugin/src/main/resources/META-INF/gradle-plugins/org.greenleaf.utils.injectplugin.properties similarity index 100% rename from plugin/src/resources/META-INF/gradle-plugins/injectplugin.properties rename to injectplugin/src/main/resources/META-INF/gradle-plugins/org.greenleaf.utils.injectplugin.properties diff --git a/library/build.gradle b/library/build.gradle index 23895e4..791c35c 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -3,17 +3,19 @@ apply plugin: 'com.novoda.bintray-release' publish { artifactId = 'utils' - userOrg = rootProject.ext.userOrg - groupId = rootProject.ext.groupId - uploadName = rootProject.ext.uploadName - publishVersion = rootProject.ext.publishVersion - desc = rootProject.ext.desc - website = rootProject.ext.website - licences = rootProject.ext.licences + userOrg = 'davy' + repoName = "maven" + groupId = 'org.greenleaf.utils' + uploadName = 'AndroidCommonUtils' + publishVersion = '1.0.0' + desc = 'useful tool for android' + website = 'https://github.com/davyjoneswang/AndroidCommonUtils' + licences = ['Apache-2.0'] } android { compileSdkVersion 25 + buildToolsVersion '25.0.3' defaultConfig { minSdkVersion 17 targetSdkVersion 25 @@ -29,7 +31,18 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - buildToolsVersion '25.0.3' + lintOptions { + abortOnError false + checkReleaseBuilds false + } +} + +tasks.withType(Javadoc) { + options { + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('encoding', 'UTF-8') + options.addStringOption('charSet', 'UTF-8') + } } dependencies { diff --git a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy deleted file mode 100644 index 46075a0..0000000 --- a/plugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy +++ /dev/null @@ -1,18 +0,0 @@ -package org.greenleaf.utils.plugin - -import org.gradle.api.Plugin -import org.gradle.api.Project - -public class InjectPlugin implements Plugin { - - @Override - void apply(Project project) { - def log = project.logger - println("========================") - println("InjectPlugin!") - println(project.version) - println("========================") - project.android.registerTransform(new OnlyCopyTransform(project)) - project.android.registerTransform(new InjectTransform(project)) - } -} \ No newline at end of file diff --git a/plugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy b/plugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy deleted file mode 100644 index 92f93d4..0000000 --- a/plugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy +++ /dev/null @@ -1,60 +0,0 @@ -package org.greenleaf.utils.plugin - -/** - * Created by davy on 2017/6/8. - */ - -import javassist.ClassPool -import javassist.CtClass -import javassist.CtConstructor - -public class Injecter { - - private static ClassPool pool = ClassPool.getDefault() - private static String injectStr = "System.out.println(\"inject Injecter\" ); "; - - public static void injectDir(String path, String packageName) { - println(path + " " + packageName) - pool.appendClassPath(path) - - File dir = new File(path) - if (dir.isDirectory()) { - dir.eachFileRecurse { File file -> - String filePath = file.absolutePath - //确保当前文件是class文件,并且不是系统自动生成的class文件 - if (filePath.endsWith(".class") - && !filePath.contains('R$') - && !filePath.contains('R.class') - && !filePath.contains("BuildConfig.class")) { - // 判断当前目录是否是在我们的应用包里面 - int index = filePath.indexOf(packageName); - println("inject:" + filePath + " " + index) - boolean isMyPackage = index != -1; - if (isMyPackage) { - int end = filePath.length() - 6 // .class = 6 - String className = filePath.substring(index, end) - .replace('\\', '.').replace('/', '.') - //开始修改class文件 - CtClass c = pool.getCtClass(className) - - if (c.isFrozen()) { - c.defrost() - } - - CtConstructor[] cts = c.getDeclaredConstructors() - if (cts == null || cts.length == 0) { - //手动创建一个构造函数 - CtConstructor constructor = new CtConstructor(new CtClass[0], c) - constructor.insertBeforeBody(injectStr) - c.addConstructor(constructor) - } else { - cts[0].insertBeforeBody(injectStr) - } - c.writeFile(path) - c.detach() - } - } - } - } - } -} \ No newline at end of file diff --git a/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar b/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..2060867506eb5eae4e2316bef13a58656b2fca44 GIT binary patch literal 37722 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 + + 4.0.0 + org.greenleaf.utils + injectplugin + 1.0.0 + + + com.android.tools.build + gradle + 2.3.3 + compile + + + org.apache.commons + commons-io + 1.3.2 + compile + + + org.javassist + javassist + 3.20.0-GA + compile + + + diff --git a/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.md5 b/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.md5 new file mode 100644 index 0000000..93845f9 --- /dev/null +++ b/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.md5 @@ -0,0 +1 @@ +8922510e11ba20a9042572eb6ce0a0af \ No newline at end of file diff --git a/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.sha1 b/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.sha1 new file mode 100644 index 0000000..53a93fd --- /dev/null +++ b/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.sha1 @@ -0,0 +1 @@ +0ed4b879372bf0c68c2fe4db9c3391c66f358874 \ No newline at end of file diff --git a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml new file mode 100644 index 0000000..80eba01 --- /dev/null +++ b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml @@ -0,0 +1,12 @@ + + + org.greenleaf.utils + injectplugin + + 1.0.0 + + 1.0.0 + + 20180610155750 + + diff --git a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.md5 b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.md5 new file mode 100644 index 0000000..84414d6 --- /dev/null +++ b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.md5 @@ -0,0 +1 @@ +e5a4906ba4fcb43f0b490d5c741460fd \ No newline at end of file diff --git a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.sha1 b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.sha1 new file mode 100644 index 0000000..a12be74 --- /dev/null +++ b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.sha1 @@ -0,0 +1 @@ +b77a73d31c7ac5bee2f0118485aacefe63c21a53 \ No newline at end of file diff --git a/samples/build.gradle b/samples/build.gradle index dc865c5..20ee5da 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -1,4 +1,10 @@ apply plugin: 'com.android.application' +apply plugin: 'org.greenleaf.utils.injectplugin' + +injectplugin { + message = "this is test Message." + injectPackages = ["org.greenleaf.utils.samples", "com.google.utils"] +} android { compileSdkVersion 25 @@ -16,7 +22,6 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - sourceSets { main { assets.srcDirs = ['src/main/assets', 'src/main/assets/'] } } buildToolsVersion '25.0.3' } @@ -25,7 +30,34 @@ dependencies { androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile project(':library') compile 'com.android.support:appcompat-v7:25.4.0' testCompile 'junit:junit:4.12' } + + +class GreetingPluginExtension { + String message + String greeter +} + +class GreetingExtensionPlugin implements Plugin { + void apply(Project project) { + // Add the 'greeting' extension object + def extension = project.extensions.create('greeting', GreetingPluginExtension) + // Add a task that uses configuration from the extension object + project.task('GreetingHelloExtension') { + doLast { + println extension.message + println extension.greeter + println "${extension.message} from ${extension.greeter}" + } + } + } +} + +apply plugin: GreetingExtensionPlugin + +greeting { + message = 'Hi' + greeter = 'Gradle' +} \ No newline at end of file diff --git a/samples/src/main/java/com/google/utils/Utils.java b/samples/src/main/java/com/google/utils/Utils.java new file mode 100644 index 0000000..e7655f3 --- /dev/null +++ b/samples/src/main/java/com/google/utils/Utils.java @@ -0,0 +1,4 @@ +package com.google.utils; + +public class Utils { +} diff --git a/samples/src/main/java/org/greenleaf/utils/samples/InjectedClsss.java b/samples/src/main/java/org/greenleaf/utils/samples/InjectedClsss.java new file mode 100644 index 0000000..04a9100 --- /dev/null +++ b/samples/src/main/java/org/greenleaf/utils/samples/InjectedClsss.java @@ -0,0 +1,7 @@ +package org.greenleaf.utils.samples; + +public class InjectedClsss { + public InjectedClsss() { + + } +} diff --git a/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java index 4a3011f..5dc544d 100644 --- a/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java +++ b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java @@ -1,125 +1,14 @@ package org.greenleaf.utils.samples; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageInfo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; -import org.greenleaf.utils.IOUtils; -import org.greenleaf.utils.XmlUtil; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; - -import java.io.IOException; -import java.io.InputStream; - public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - - PackageInfo packageInfo = getPackageManager().getPackageArchiveInfo("", 0); - ActivityInfo[] activities = packageInfo.activities; - activities[0].getThemeResource(); - - InputStream inputStream = null; - try { - inputStream = getAssets().open("AndroidManifest.xml"); - int length = inputStream.available(); - byte[] datas = new byte[length]; - getAssets().open("AndroidManifest.xml").read(datas); - String content = new String(datas); - content = content.replaceAll("\\s*\n\\s*", ""); - System.out.println(content); - Document document = XmlUtil.parserXml(content); - System.out.println(document.getXmlEncoding() + "-" + document.getXmlVersion() + "-" + document.getXmlStandalone()); - StringBuilder stringBuilder = new StringBuilder(); - printNode("=", document, stringBuilder); - System.out.println(stringBuilder.toString()); - } catch (IOException e) { - e.printStackTrace(); - } finally { - IOUtils.closeQuietly(inputStream); - } - } - - private String nodeType2String(short type) { - String str = "WRONG_TYTPE"; - switch (type) { - case 1: - str = "ELEMENT"; - break; - case 2: - str = "ATTRIBUTE"; - break; - case 3: - str = "TEXT"; - break; - case 4: - str = "CDATA_SECTION"; - break; - case 5: - str = "ENTITY_REFERENCE"; - break; - case 6: - str = "ENTITY"; - break; - case 7: - str = "PROCESSING_INSTRUCTION"; - break; - case 8: - str = "COMMENT"; - break; - case 9: - str = "DOCUMENT"; - break; - case 10: - str = "DOCUMENT_TYPE"; - break; - case 11: - str = "DOCUMENT_FRAGMENT"; - break; - case 12: - str = "NOTATION"; - break; - } - return str; - } - - private void printNode(String prex, Node node, StringBuilder stringBuilder) { - if (node == null) { - return; - } - stringBuilder.append(prex).append("name:" + node.getNodeName() + " \n") - .append(prex).append("type:" + nodeType2String(node.getNodeType()) + " \n") - .append(prex).append("value:" + node.getNodeValue() + " \n") - .append(prex).append("nsUrl:" + node.getNamespaceURI() + " \n") - .append(prex).append("Attrs:\n" + printNodeMap(node.getAttributes()) + " \n"); - - if (node.getChildNodes() != null && node.getChildNodes().getLength() > 0) { - for (int i = 0; i < node.getChildNodes().getLength(); i++) { - printNode(prex + "=", node.getChildNodes().item(i), stringBuilder); - } - } - } - - private String printNodeMap(NamedNodeMap nodemap) { - if (nodemap == null) { - return "\n"; - } - StringBuilder stringBuilder = new StringBuilder(); - int len = nodemap.getLength(); - - if (len > 0) { - for (int i = 0; i < len; i++) { - stringBuilder.append(nodemap.item(i).getNodeName() + ":=" + nodemap.item(i).getNodeValue() + "\n"); - } - } else { - stringBuilder.append("\n"); - } - return stringBuilder.toString(); + new InjectedClsss(); } } diff --git a/settings.gradle b/settings.gradle index e4c75e6..7c9baa2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':samples', ':library', ':plugin' +include ':samples', ':library', ':injectplugin' From 40d764475fe59610cd21807eb33a40a6a2362e34 Mon Sep 17 00:00:00 2001 From: wangyh <1051522865@qq.com> Date: Mon, 11 Jun 2018 00:13:08 +0800 Subject: [PATCH 09/13] update 1.0.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ff3af3e..cae06b9 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ ext { repoName = "maven" groupId = 'org.greenleaf.utils' uploadName = 'AndroidInjectPlugin' - publishVersion = '1.0.0' + publishVersion = '1.0.1' desc = 'useful tool for android' website = 'https://github.com/davyjoneswang/AndroidCommonUtils' licences = ['Apache-2.0'] From 95da62cab51ebb5acecb41c1200457e39b499c12 Mon Sep 17 00:00:00 2001 From: wangyh <1051522865@qq.com> Date: Mon, 11 Jun 2018 00:18:08 +0800 Subject: [PATCH 10/13] update files --- .idea/caches/build_file_checksums.ser | Bin 648 -> 648 bytes build.gradle | 2 -- injectplugin/build.gradle | 5 +++-- library/build.gradle | 15 +++++++++------ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index a64132d8902563e2483676955cbdf64f89414da4..f5ac0f037c6f38a28dbe6875659936d9fd0c1262 100644 GIT binary patch delta 117 zcmV-*0E+*J1&9TZnFD=BE0LV65CgSP&H0_`j{~M99}hk5-wwELyBlMn)UATux0 delta 117 zcmV-*0E+*J1&9TZnFDQ=J&~NO5bS-X9k0WVXF+jYRX}I^f0I}NAvwW5@I3T8B%j3( zbFBN_HHvfq3}SU@Y-BEHa$#g_Wp!}?egFml000m;LTeY3@~uYqlX4kT2|9q2vH?yI Xxh`vn!usbH`~a3u@yp3-lMn)UL(4GU diff --git a/build.gradle b/build.gradle index cae06b9..bb92a7b 100644 --- a/build.gradle +++ b/build.gradle @@ -30,8 +30,6 @@ ext { userOrg = 'davy' repoName = "maven" groupId = 'org.greenleaf.utils' - uploadName = 'AndroidInjectPlugin' - publishVersion = '1.0.1' desc = 'useful tool for android' website = 'https://github.com/davyjoneswang/AndroidCommonUtils' licences = ['Apache-2.0'] diff --git a/injectplugin/build.gradle b/injectplugin/build.gradle index 783e50c..e046897 100644 --- a/injectplugin/build.gradle +++ b/injectplugin/build.gradle @@ -4,11 +4,12 @@ apply plugin: 'maven' publish { artifactId = 'injectplugin' + uploadName = 'AndroidInjectPlugin' + publishVersion = '1.0.1' + userOrg = rootProject.ext.userOrg repoName = rootProject.ext.repoName groupId = rootProject.ext.groupId - uploadName = rootProject.ext.uploadName - publishVersion = rootProject.ext.publishVersion desc = rootProject.ext.desc website = rootProject.ext.website licences = rootProject.ext.licences diff --git a/library/build.gradle b/library/build.gradle index 791c35c..fa5b6c8 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -3,14 +3,17 @@ apply plugin: 'com.novoda.bintray-release' publish { artifactId = 'utils' - userOrg = 'davy' - repoName = "maven" - groupId = 'org.greenleaf.utils' uploadName = 'AndroidCommonUtils' publishVersion = '1.0.0' - desc = 'useful tool for android' - website = 'https://github.com/davyjoneswang/AndroidCommonUtils' - licences = ['Apache-2.0'] + + userOrg = rootProject.ext.userOrg + repoName = rootProject.ext.repoName + groupId = rootProject.ext.groupId + desc = rootProject.ext.desc + website = rootProject.ext.website + licences = rootProject.ext.licences + bintrayUser = BINTRAY_USER + bintrayKey = BINTRAY_KEY } android { From 8c753f24ccc716b25ff29940d463fbcbbbcd8e2d Mon Sep 17 00:00:00 2001 From: Davy Date: Thu, 23 Mar 2023 12:57:53 +0800 Subject: [PATCH 11/13] v1 --- .gitignore | 1 + .idea/compiler.xml | 6 ++ .idea/gradle.xml | 6 +- .idea/jarRepositories.xml | 40 +++++++++ .idea/misc.xml | 20 ++++- .idea/modules.xml | 16 +++- .idea/runConfigurations.xml | 12 --- build.gradle | 8 +- gradle/wrapper/gradle-wrapper.properties | 3 +- injectplugin/build.gradle | 49 +++++------ .../utils/plugin/InjectPlugin.groovy | 3 +- library/build.gradle | 80 ++++++++++++------ .../injectplugin/1.0.0/injectplugin-1.0.0.jar | Bin 37722 -> 0 bytes .../1.0.0/injectplugin-1.0.0.jar.md5 | 1 - .../1.0.0/injectplugin-1.0.0.jar.sha1 | 1 - .../injectplugin/1.0.0/injectplugin-1.0.0.pom | 28 ------ .../1.0.0/injectplugin-1.0.0.pom.md5 | 1 - .../1.0.0/injectplugin-1.0.0.pom.sha1 | 1 - .../utils/injectplugin/maven-metadata.xml | 12 --- .../utils/injectplugin/maven-metadata.xml.md5 | 1 - .../injectplugin/maven-metadata.xml.sha1 | 1 - samples/build.gradle | 71 +++++++--------- .../greenleaf/utils/samples/MainActivity.java | 8 ++ settings.gradle | 3 +- 24 files changed, 205 insertions(+), 167 deletions(-) create mode 100644 .idea/compiler.xml create mode 100644 .idea/jarRepositories.xml delete mode 100644 .idea/runConfigurations.xml delete mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar delete mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar.md5 delete mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar.sha1 delete mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom delete mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.md5 delete mode 100644 repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.sha1 delete mode 100644 repo/org/greenleaf/utils/injectplugin/maven-metadata.xml delete mode 100644 repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.md5 delete mode 100644 repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.sha1 diff --git a/.gitignore b/.gitignore index 910e696..59c21df 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,4 @@ library/src/main/res/drawable/ samples/libs/ samples/src/main/res/drawable/ .idea/misc.xml +/repo/ diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index a5500aa..310c65f 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,19 +1,21 @@ + diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..3c5b05a --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 99202cc..169093e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,27 +5,41 @@ - + diff --git a/.idea/modules.xml b/.idea/modules.xml index e6802ff..a0c2092 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,10 +2,18 @@ - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/build.gradle b/build.gradle index bb92a7b..b35237c 100644 --- a/build.gradle +++ b/build.gradle @@ -4,14 +4,9 @@ buildscript { repositories { jcenter() google() - maven{ - url uri('./repo') - } } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' - classpath 'com.novoda:bintray-release:0.8.1' - classpath 'org.greenleaf.utils:injectplugin:1.0.0' + classpath 'com.android.tools.build:gradle:4.2.2' } } @@ -30,6 +25,7 @@ ext { userOrg = 'davy' repoName = "maven" groupId = 'org.greenleaf.utils' + version = '1.0.0' desc = 'useful tool for android' website = 'https://github.com/davyjoneswang/AndroidCommonUtils' licences = ['Apache-2.0'] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7e06bb7..4d9ca16 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Thu Jun 07 22:54:29 CST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/injectplugin/build.gradle b/injectplugin/build.gradle index e046897..be7b691 100644 --- a/injectplugin/build.gradle +++ b/injectplugin/build.gradle @@ -1,40 +1,35 @@ apply plugin: 'groovy' -apply plugin: 'com.novoda.bintray-release' -apply plugin: 'maven' - -publish { - artifactId = 'injectplugin' - uploadName = 'AndroidInjectPlugin' - publishVersion = '1.0.1' - - userOrg = rootProject.ext.userOrg - repoName = rootProject.ext.repoName - groupId = rootProject.ext.groupId - desc = rootProject.ext.desc - website = rootProject.ext.website - licences = rootProject.ext.licences - bintrayUser = BINTRAY_USER - bintrayKey = BINTRAY_KEY -} +apply plugin: 'maven-publish' dependencies { compile gradleApi()//gradle sdk compile localGroovy() - compile 'com.android.tools.build:gradle:2.3.3' + compile 'com.android.tools.build:gradle:3.2.0' compile 'org.apache.commons:commons-io:1.3.2' compile 'org.javassist:javassist:3.20.0-GA' } +task generateSourcesJar(type: Jar) { + from sourceSets.main.java.srcDirs + classifier 'sources' +} -//设置maven deployer -uploadArchives { - repositories { - mavenDeployer { - pom.artifactId = 'injectplugin' - pom.groupId = 'org.greenleaf.utils' - pom.version = '1.0.0' - //文件发布到下面目录 - repository(url: uri('../repo')) +//发布maven库 +publishing { + //配置maven-publishing插件的输出物 + publications { + maven(MavenPublication) { + from components.java + //发布仓库的文件路径 + groupId = rootProject.ext.groupId + //库名 + artifactId = 'injectplugin' + //版本号 + version = rootProject.ext.version + //指定打包路径 + // artifact "$buildDir/outputs/aar/${project.name}-release.aar" + // 上传source,这样使用方可以看到方法注释 + artifact generateSourcesJar } } } \ No newline at end of file diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy index e629884..711c529 100644 --- a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy +++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy @@ -18,12 +18,13 @@ public class InjectPlugin implements Plugin { def injectExtension = project.extensions.create('injectplugin', InjectExtension) println(injectExtension) //这里返回空,afterEvaluate才能获得值 + mLogger.info("========================") project.afterEvaluate { println(injectExtension) } - project.android.registerTransform(new OnlyCopyTransform(project)) +// project.android.registerTransform(new OnlyCopyTransform(project)) project.android.registerTransform(new InjectTransform(project, injectExtension)) } diff --git a/library/build.gradle b/library/build.gradle index fa5b6c8..85018ca 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,20 +1,18 @@ apply plugin: 'com.android.library' -apply plugin: 'com.novoda.bintray-release' - -publish { - artifactId = 'utils' - uploadName = 'AndroidCommonUtils' - publishVersion = '1.0.0' - - userOrg = rootProject.ext.userOrg - repoName = rootProject.ext.repoName - groupId = rootProject.ext.groupId - desc = rootProject.ext.desc - website = rootProject.ext.website - licences = rootProject.ext.licences - bintrayUser = BINTRAY_USER - bintrayKey = BINTRAY_KEY -} +apply plugin: 'maven-publish' + +//publish { +// artifactId = 'utils' +// uploadName = 'AndroidCommonUtils' +// publishVersion = '1.0.0' +// +// userOrg = rootProject.ext.userOrg +// repoName = rootProject.ext.repoName +// groupId = rootProject.ext.groupId +// desc = rootProject.ext.desc +// website = rootProject.ext.website +// licences = rootProject.ext.licences +//} android { compileSdkVersion 25 @@ -22,8 +20,6 @@ android { defaultConfig { minSdkVersion 17 targetSdkVersion 25 - versionCode 1 - versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -38,6 +34,10 @@ android { abortOnError false checkReleaseBuilds false } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } tasks.withType(Javadoc) { @@ -49,10 +49,42 @@ tasks.withType(Javadoc) { } dependencies { - compile fileTree(include: ['*.jar'], dir: 'libs') - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - compile 'com.android.support:appcompat-v7:25.4.0' - testCompile 'junit:junit:4.12' + api fileTree(include: ['*.jar'], dir: 'libs') + api 'com.android.support:appcompat-v7:25.4.0' } + +task generateSourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier 'sources' +} + +afterEvaluate { + publishing { + publications { + // Creates a Maven publication called "release". + release(MavenPublication) { + // Applies the component for the release build variant. + from components.release + + // You can then customize attributes of the publication as shown below. + groupId = rootProject.ext.groupId + artifactId = 'utils' + version = rootProject.ext.version + + // 上传source,这样使用方可以看到方法注释 + artifact generateSourcesJar + } + // Creates a Maven publication called “debug”. + debug(MavenPublication) { + // Applies the component for the debug build variant. + from components.debug + + groupId = rootProject.ext.groupId + artifactId = 'utils' + version = rootProject.ext.version + "-SNAPSHOT" + // 上传source,这样使用方可以看到方法注释 + artifact generateSourcesJar + } + } + } +} \ No newline at end of file diff --git a/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar b/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.jar deleted file mode 100644 index 2060867506eb5eae4e2316bef13a58656b2fca44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37722 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 - - 4.0.0 - org.greenleaf.utils - injectplugin - 1.0.0 - - - com.android.tools.build - gradle - 2.3.3 - compile - - - org.apache.commons - commons-io - 1.3.2 - compile - - - org.javassist - javassist - 3.20.0-GA - compile - - - diff --git a/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.md5 b/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.md5 deleted file mode 100644 index 93845f9..0000000 --- a/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.md5 +++ /dev/null @@ -1 +0,0 @@ -8922510e11ba20a9042572eb6ce0a0af \ No newline at end of file diff --git a/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.sha1 b/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.sha1 deleted file mode 100644 index 53a93fd..0000000 --- a/repo/org/greenleaf/utils/injectplugin/1.0.0/injectplugin-1.0.0.pom.sha1 +++ /dev/null @@ -1 +0,0 @@ -0ed4b879372bf0c68c2fe4db9c3391c66f358874 \ No newline at end of file diff --git a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml deleted file mode 100644 index 80eba01..0000000 --- a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - org.greenleaf.utils - injectplugin - - 1.0.0 - - 1.0.0 - - 20180610155750 - - diff --git a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.md5 b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.md5 deleted file mode 100644 index 84414d6..0000000 --- a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.md5 +++ /dev/null @@ -1 +0,0 @@ -e5a4906ba4fcb43f0b490d5c741460fd \ No newline at end of file diff --git a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.sha1 b/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.sha1 deleted file mode 100644 index a12be74..0000000 --- a/repo/org/greenleaf/utils/injectplugin/maven-metadata.xml.sha1 +++ /dev/null @@ -1 +0,0 @@ -b77a73d31c7ac5bee2f0118485aacefe63c21a53 \ No newline at end of file diff --git a/samples/build.gradle b/samples/build.gradle index 20ee5da..f81717a 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -1,10 +1,10 @@ apply plugin: 'com.android.application' -apply plugin: 'org.greenleaf.utils.injectplugin' +//apply plugin: 'org.greenleaf.utils.injectplugin' -injectplugin { - message = "this is test Message." - injectPackages = ["org.greenleaf.utils.samples", "com.google.utils"] -} +//injectplugin { +// message = "this is test Message." +// injectPackages = ["org.greenleaf.utils.samples", "com.google.utils"] +//} android { compileSdkVersion 25 @@ -23,41 +23,34 @@ android { } } buildToolsVersion '25.0.3' -} -dependencies { - compile fileTree(include: ['*.jar'], dir: 'libs') - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - compile 'com.android.support:appcompat-v7:25.4.0' - testCompile 'junit:junit:4.12' -} - - -class GreetingPluginExtension { - String message - String greeter -} - -class GreetingExtensionPlugin implements Plugin { - void apply(Project project) { - // Add the 'greeting' extension object - def extension = project.extensions.create('greeting', GreetingPluginExtension) - // Add a task that uses configuration from the extension object - project.task('GreetingHelloExtension') { - doLast { - println extension.message - println extension.greeter - println "${extension.message} from ${extension.greeter}" - } - } + lintOptions { + checkReleaseBuilds false + // Or, if you prefer, you can continue to check for errors in release builds, + // but continue the build even when errors are found: + abortOnError false + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } } -apply plugin: GreetingExtensionPlugin - -greeting { - message = 'Hi' - greeter = 'Gradle' -} \ No newline at end of file +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'com.android.support:appcompat-v7:25.4.0' + implementation project(path: ':library') +} +// +//buildscript { +// repositories { +// mavenCentral() +// google() +// maven{ +// url uri('../repo') +// } +// } +// dependencies { +// classpath 'org.greenleaf.utils:injectplugin:1.0.0' +// } +//} \ No newline at end of file diff --git a/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java index 5dc544d..6d24c2d 100644 --- a/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java +++ b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java @@ -3,12 +3,20 @@ import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import org.greenleaf.utils.AssetsUtils; + public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + new Thread(new Runnable() { + @Override + public void run() { + AssetsUtils.asset2String(getApplicationContext(), "data.xml"); + } + }).start(); new InjectedClsss(); } } diff --git a/settings.gradle b/settings.gradle index 7c9baa2..1c651fc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,2 @@ -include ':samples', ':library', ':injectplugin' +include ':samples', ':library' +//, ':injectplugin' From ecbef75957238134b03be0a0207a0c47ac638f8a Mon Sep 17 00:00:00 2001 From: Davy Date: Thu, 23 Mar 2023 13:20:47 +0800 Subject: [PATCH 12/13] v1 --- library/build.gradle | 9 ++++--- .../samples/ExampleInstrumentedTest.java | 26 ------------------- .../utils/samples/ExampleUnitTest.java | 17 ------------ 3 files changed, 6 insertions(+), 46 deletions(-) delete mode 100644 samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java delete mode 100644 samples/src/test/java/org/greenleaf/utils/samples/ExampleUnitTest.java diff --git a/library/build.gradle b/library/build.gradle index 85018ca..8bc5293 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -20,9 +20,6 @@ android { defaultConfig { minSdkVersion 17 targetSdkVersion 25 - - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } buildTypes { release { @@ -32,7 +29,13 @@ android { } lintOptions { abortOnError false + checkDependencies true checkReleaseBuilds false + // Or, if you prefer, you can continue to check for errors in release builds, + // but continue the build even when errors are found: + abortOnError false + // The demo app does not have translations. + disable 'MissingTranslation' } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 diff --git a/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java b/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java deleted file mode 100644 index 0fa6420..0000000 --- a/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.greenleaf.utils.samples; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumentation test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("org.davy.commons", appContext.getPackageName()); - } -} diff --git a/samples/src/test/java/org/greenleaf/utils/samples/ExampleUnitTest.java b/samples/src/test/java/org/greenleaf/utils/samples/ExampleUnitTest.java deleted file mode 100644 index 470a0e1..0000000 --- a/samples/src/test/java/org/greenleaf/utils/samples/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.greenleaf.utils.samples; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file From 0473fd7ac1ec9b62701c53c8d69212ba09f9f65c Mon Sep 17 00:00:00 2001 From: Davy Date: Thu, 23 Mar 2023 13:44:41 +0800 Subject: [PATCH 13/13] v1 --- .../samples/ExampleInstrumentedTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java diff --git a/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java b/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java new file mode 100644 index 0000000..0fa6420 --- /dev/null +++ b/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package org.greenleaf.utils.samples; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("org.davy.commons", appContext.getPackageName()); + } +}