| /* |
| * 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 com.taobao.weex.utils; |
| |
| import android.app.ActivityManager; |
| import android.content.Context; |
| import android.content.res.Configuration; |
| import android.os.Looper; |
| import android.os.SystemClock; |
| import android.support.annotation.Nullable; |
| import android.support.v4.util.LruCache; |
| import android.text.TextUtils; |
| import com.taobao.weex.WXEnvironment; |
| import com.taobao.weex.WXSDKManager; |
| import com.taobao.weex.adapter.IWXConfigAdapter; |
| import com.taobao.weex.common.Constants; |
| |
| public class WXUtils { |
| |
| final static LruCache<String, Integer> sCache = new LruCache<>(64); |
| public static final char PERCENT = '%'; |
| private static final int HUNDRED =100; |
| /** |
| * Tell whether current thread is UI(main) thread. |
| * @return true for UI(main) thread |
| */ |
| public static boolean isUiThread() { |
| return Thread.currentThread().getId() == Looper.getMainLooper().getThread().getId(); |
| } |
| |
| public static boolean isUndefined(float value) { |
| return Float.isNaN(value); |
| } |
| |
| |
| public static float getFloatByViewport(Object value, int viewport) { |
| if (value == null) { |
| return Float.NaN; |
| } |
| String temp = value.toString().trim(); |
| if (Constants.Name.AUTO.equals(temp) |
| || Constants.Name.UNDEFINED.equals(temp) |
| || TextUtils.isEmpty(temp)) { |
| WXLogUtils.e("Argument Warning ! value is " + temp + "And default Value:" + Float.NaN); |
| return Float.NaN; |
| } |
| |
| if (temp.endsWith("wx")) { |
| try { |
| return transferWx(temp, viewport); |
| } catch (NumberFormatException e) { |
| WXLogUtils.e("Argument format error! value is " + value, e); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } else if (temp.endsWith("px")) { |
| try { |
| temp = temp.substring(0, temp.indexOf("px")); |
| return Float.parseFloat(temp); |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } else { |
| try { |
| return Float.parseFloat(temp); |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } |
| return Float.NaN; |
| } |
| |
| public static float getFloat(Object value) { |
| return getFloat(value, Float.NaN); |
| } |
| |
| public static Float getFloat(Object value, @Nullable Float df) { |
| if (value == null) { |
| return df; |
| } |
| |
| String temp = value.toString().trim(); |
| if(Constants.Name.AUTO.equals(temp) |
| || Constants.Name.UNDEFINED.equals(temp) |
| || TextUtils.isEmpty(temp)){ |
| WXLogUtils.e("Argument Warning ! value is " + temp + "And default Value:"+Float.NaN); |
| return df; |
| } |
| if (temp.endsWith("wx")) { |
| try { |
| return transferWx(temp, 750); |
| } catch (NumberFormatException e) { |
| WXLogUtils.e("Argument format error! value is " + value, e); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| }else if (temp.endsWith("px")) { |
| try { |
| temp = temp.substring(0, temp.indexOf("px")); |
| return Float.parseFloat(temp); |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| }else { |
| try { |
| return Float.parseFloat(temp); |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } |
| return df; |
| } |
| |
| private static float transferWx(String stringWithWXPostfix, int viewport) { |
| if(null == stringWithWXPostfix) { |
| return 0; |
| } |
| String temp = stringWithWXPostfix; |
| if(stringWithWXPostfix.endsWith("wx")) { |
| temp = stringWithWXPostfix.substring(0, stringWithWXPostfix.indexOf("wx")); |
| } |
| Float f = Float.parseFloat(temp); |
| float density = WXEnvironment.sApplication.getResources().getDisplayMetrics().density; |
| return density * f * viewport / WXViewUtils.getScreenWidth(); |
| } |
| |
| public static float fastGetFloat(String raw, int precision){ |
| if(!TextUtils.isEmpty(raw)){ |
| boolean positive=true; |
| int loc=0; |
| if(raw.charAt(0)=='-'){ |
| positive=false; |
| loc++; |
| } |
| else if(raw.charAt(0)=='+'){ |
| loc++; |
| } |
| |
| char digit; |
| float result=0; |
| while (loc<raw.length() && (digit=raw.charAt(loc))>='0'&&digit<='9'){ |
| result=result*10+digit-'0'; |
| loc++; |
| } |
| |
| if(loc<raw.length()){ |
| if(raw.charAt(loc)=='.'){ |
| loc++; |
| int remainderLength=10; |
| int counter=0; |
| while(loc<raw.length() && |
| counter<precision && |
| ((digit=raw.charAt(loc))>='0'&& digit<='9')){ |
| result+=(digit-'0')/(float)remainderLength; |
| remainderLength*=10; |
| loc++; |
| counter++; |
| } |
| } |
| else{ |
| // throw new NumberFormatException("Illegal separator"); |
| } |
| } |
| |
| if(!positive) |
| result*=-1; |
| return result; |
| } |
| return 0; |
| // throw new NumberFormatException("NullNumber"); |
| } |
| |
| /** |
| * Parse string representation of float. This method intend to be faster than |
| * {@link Float#parseFloat(String)}, but less accuracy. |
| * @param raw |
| * @return |
| */ |
| public static float fastGetFloat(String raw){ |
| return fastGetFloat(raw, Integer.MAX_VALUE); |
| } |
| |
| public static int parseInt(String value) { |
| try { |
| if (!TextUtils.isEmpty(value) && !value.contains(".")) { |
| return Integer.parseInt(value); |
| } |
| } catch (NumberFormatException e) { |
| if (WXEnvironment.isApkDebugable()) { |
| WXLogUtils.e(WXLogUtils.getStackTrace(e)); |
| } |
| } |
| return 0; |
| } |
| |
| public static int parseInt(Object value) { |
| return parseInt(String.valueOf(value)); |
| } |
| |
| public static float parseFloat(Object value) { |
| return parseFloat(String.valueOf(value)); |
| } |
| |
| public static float parseFloat(String value) { |
| try { |
| if (!TextUtils.isEmpty(value) && !TextUtils.equals(value, "null")) { |
| return Float.parseFloat(value); |
| } else { |
| if (WXEnvironment.isApkDebugable()) { |
| WXLogUtils.e("WXUtils parseFloat illegal value is " + value); |
| } |
| } |
| } catch (NumberFormatException e) { |
| if (WXEnvironment.isApkDebugable()) { |
| WXLogUtils.e(WXLogUtils.getStackTrace(e)); |
| } |
| } |
| return 0; |
| } |
| |
| public static int getInt(Object value) { |
| return getInteger(value, 0); |
| } |
| |
| public static @Nullable Integer getInteger(@Nullable Object value, @Nullable Integer df) { |
| |
| if (value == null) { |
| return df; |
| } |
| |
| String temp = value.toString().trim(); |
| String key = temp; |
| Integer cache = sCache.get(key); |
| if (cache != null) { |
| return cache; |
| } else { |
| Integer ret = df; |
| String suffix = ""; |
| if (temp.length() >= 2) { |
| suffix = temp.substring(temp.length() - 2, temp.length()); |
| } |
| |
| if (TextUtils.equals("wx", suffix)) { |
| if (WXEnvironment.isApkDebugable()) { |
| WXLogUtils |
| .w("the value of " + value |
| + " use wx unit, which will be not supported soon after."); |
| } |
| try { |
| ret = (int)transferWx(temp, 750); |
| } catch (NumberFormatException e) { |
| WXLogUtils.e("Argument format error! value is " + value, e); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } else if (TextUtils.equals("px", suffix)) { |
| try { |
| temp = temp.substring(0, temp.length() - 2); |
| if (!TextUtils.isEmpty(temp) && temp.contains(".")) { |
| ret = (int)WXUtils.parseFloat(temp); |
| } else { |
| ret = Integer.parseInt(temp); |
| } |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } else { |
| try { |
| if (!TextUtils.isEmpty(temp)) { |
| if (temp.contains(".")) { |
| ret = (int)WXUtils.parseFloat(temp); |
| } else { |
| ret = Integer.parseInt(temp); |
| } |
| } else { |
| if (WXEnvironment.isApkDebugable()) { |
| WXLogUtils.e("Argument value is null, df is" + df); |
| } |
| } |
| } catch (NumberFormatException nfe) { |
| if (WXEnvironment.isApkDebugable()) { |
| WXLogUtils.w("The parameter format is not supported", nfe); |
| } |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } |
| if (ret != null && !ret.equals(df)) { |
| sCache.put(key, ret); |
| } |
| return ret; |
| } |
| } |
| |
| /** |
| * Looks like no longer usage exists, Mark deprecate first. |
| * @param value |
| * @return |
| */ |
| @Deprecated |
| public static long getLong(Object value) { |
| if (value == null) { |
| return 0; |
| } |
| long result = 0; |
| String temp = value.toString().trim(); |
| if (temp.endsWith("wx")) { |
| if (WXEnvironment.isApkDebugable()) { |
| WXLogUtils.w("the value of " + value + " use wx unit, which will be not supported soon after."); |
| } |
| try { |
| return (long)transferWx(temp, 750); |
| } catch (NumberFormatException e) { |
| WXLogUtils.e("Argument format error! value is " + value, e); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| }else if (temp.endsWith("px")) { |
| try { |
| temp = temp.substring(0, temp.indexOf("px")); |
| return Long.parseLong(temp); |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| }else { |
| try { |
| return Long.parseLong(temp); |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Looks like no longer usage exists, Mark deprecate first. |
| * @param value |
| * @return |
| */ |
| @Deprecated |
| public static double getDouble(Object value) { |
| if (value == null) { |
| return 0; |
| } |
| double result = 0; |
| String temp = value.toString().trim(); |
| if (temp.endsWith("wx")) { |
| if (WXEnvironment.isApkDebugable()) { |
| WXLogUtils.w("the value of " + value + " use wx unit, which will be not supported soon after."); |
| } |
| try { |
| return transferWx(temp, 750); |
| } catch (NumberFormatException e) { |
| WXLogUtils.e("Argument format error! value is " + value, e); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| }else if (temp.endsWith("px")) { |
| try { |
| temp = temp.substring(0, temp.indexOf("px")); |
| return Double.parseDouble(temp); |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| }else { |
| try { |
| return Double.parseDouble(temp); |
| } catch (NumberFormatException nfe) { |
| WXLogUtils.e("Argument format error! value is " + value, nfe); |
| } catch (Exception e) { |
| WXLogUtils.e("Argument error! value is " + value, e); |
| } |
| } |
| |
| return result; |
| } |
| |
| @Deprecated |
| public static boolean isTabletDevice() { |
| try{ |
| return (WXEnvironment.getApplication().getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; |
| }catch (Exception e){ |
| // |
| } |
| return false; |
| } |
| |
| public static Boolean getBoolean(@Nullable Object value, @Nullable Boolean df) { |
| |
| if (value == null) |
| return df; |
| if (TextUtils.equals("false",value.toString())) { |
| return false; |
| } else if (TextUtils.equals("true",value.toString())) { |
| return true; |
| } |
| return df; |
| } |
| |
| public static long getAvailMemory(Context context){ |
| ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); |
| ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo(); |
| am.getMemoryInfo(mi); |
| //mi.availMem; |
| //return Formatter.formatFileSize(context, mi.availMem); |
| WXLogUtils.w("app AvailMemory ---->>>"+mi.availMem/(1024*1024)); |
| return mi.availMem/(1024*1024); |
| } |
| |
| public static String getString(@Nullable Object value,@Nullable String df) { |
| |
| if (value == null) |
| return df; |
| |
| String originValue; |
| if (value instanceof String) { |
| originValue = (String) value; |
| } else { |
| originValue = value.toString(); |
| } |
| |
| return originValue; |
| } |
| |
| public static int parseUnitOrPercent(String raw, int unit) { |
| int suffix; |
| if ((suffix = raw.lastIndexOf(WXUtils.PERCENT)) != -1) { |
| return parsePercent(raw.substring(0, suffix), unit); |
| } |
| else { |
| return WXUtils.parseInt(raw); |
| } |
| } |
| |
| private static int parsePercent(String raw, int unit){ |
| return (int)(Float.parseFloat(raw) / HUNDRED * unit); |
| } |
| |
| /** |
| * Get a banner data in JSON format from a bundle content. |
| * A bundle banner looks like below: |
| * \/*!count |
| * * { |
| * * version: "0.2.1.20170104-release", |
| * * create: "20170207171112", |
| * * git: "banner--772c915", |
| * * digest: "c709b7f91867e371b24f54d6aeea232a" |
| * * } |
| * !*\/ |
| * |
| * @param content a bundle content |
| * @return |
| */ |
| public static String getBundleBanner(String content) { |
| final String commentBegin = "/*!"; |
| final String commentEnd = "!*/"; |
| final String asteriskRegex = "\\*"; |
| final String replacement = ""; |
| |
| int offsetCountBegin = content.indexOf(commentBegin); |
| if (offsetCountBegin == -1) { |
| return null; |
| } |
| offsetCountBegin += commentBegin.length(); |
| int offsetCountEnd = indexLineBreak(content, offsetCountBegin); |
| if (offsetCountEnd == -1) { |
| return null; |
| } |
| String countStr = content.substring(offsetCountBegin, offsetCountEnd); |
| int count = Integer.parseInt(countStr); |
| |
| String commentBody = content.substring(offsetCountEnd + 1, offsetCountEnd + 1 + count); |
| int offsetBodyEnd = commentBody.lastIndexOf(commentEnd); |
| if (offsetBodyEnd == -1) { |
| return null; |
| } |
| commentBody = commentBody.substring(0, offsetBodyEnd); |
| |
| StringBuilder commentBodyBuilder = new StringBuilder(); |
| String[] items = splitLineBreak(commentBody); |
| |
| for (String item : items) { |
| commentBodyBuilder.append(item.replaceFirst(asteriskRegex, replacement)); |
| } |
| |
| return commentBodyBuilder.toString(); |
| } |
| |
| private static int indexLineBreak(String str, int fromIndex) { |
| final String lineBreakIos = "\r"; |
| final String lineBreakUnix = "\n"; |
| final String linebreakWin = "\r\n"; |
| |
| int index = str.indexOf(lineBreakIos, fromIndex); |
| if (index == -1) { |
| index = str.indexOf(lineBreakUnix, fromIndex); |
| } |
| if (index == -1) { |
| index = str.indexOf(linebreakWin, fromIndex); |
| } |
| |
| return index; |
| } |
| |
| private static String[] splitLineBreak(String str) { |
| final String lineBreakIos = "\r"; |
| final String lineBreakUnix = "\n"; |
| final String linebreakWin = "\r\n"; |
| String[] items = str.split(lineBreakIos); |
| |
| if (items.length == 1) { |
| items = str.split(lineBreakUnix); |
| } |
| if (items.length == 1) { |
| items = str.split(linebreakWin); |
| } |
| |
| return items; |
| } |
| |
| |
| |
| /** |
| * get number |
| * */ |
| public static int getNumberInt(Object value, int defaultValue){ |
| if(value == null){ |
| return defaultValue; |
| } |
| if(value instanceof Number){ |
| return ((Number) value).intValue(); |
| } |
| try{ |
| String number = value.toString(); |
| if(number.indexOf('.') >= 0) { |
| return (int) Float.parseFloat(value.toString()); |
| }else{ |
| return Integer.parseInt(number); |
| } |
| }catch (Exception e){return defaultValue;} |
| } |
| |
| public static boolean checkGreyConfig(String group,String key,String defaultValue){ |
| IWXConfigAdapter configAdapter = WXSDKManager.getInstance().getWxConfigAdapter(); |
| if (null == configAdapter) { |
| return false; |
| } |
| double randomValue = Math.random() * 100; |
| double max = 100; |
| try { |
| String configValue = configAdapter.getConfig(group, key, defaultValue); |
| max = Double.valueOf(configValue); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return randomValue < max; |
| } |
| |
| private static final long sInterval = System.currentTimeMillis() - SystemClock.uptimeMillis(); |
| |
| public static long getFixUnixTime(){ |
| return sInterval + SystemClock.uptimeMillis(); |
| } |
| |
| } |