提交 e66a4325 编写于 作者: [ [linjizong]

Merge remote-tracking branch 'origin/master'

......@@ -6,6 +6,7 @@ import com.didichuxing.doraemonkit.kit.AbstractKit
import com.didichuxing.doraemonkit.kit.Category
import com.didichuxing.doraemonkit.kit.core.DokitIntent
import com.didichuxing.doraemonkit.kit.core.DokitViewManager
import com.didichuxing.doraemonkit.kit.core.SimpleDokitStarter
/**
* ================================================
......@@ -25,9 +26,7 @@ class DemoKit : AbstractKit() {
get() = R.mipmap.dk_sys_info
override fun onClick(context: Context?) {
val dokitIntent = DokitIntent(DemoDokitView::class.java)
dokitIntent.mode = DokitIntent.MODE_SINGLE_INSTANCE
DokitViewManager.getInstance().attach(dokitIntent)
SimpleDokitStarter.startFloating(DemoDokitView::class.java)
}
override fun onAppInit(context: Context?) {
......
......@@ -14,7 +14,6 @@ import com.didiglobal.booster.gradle.getProperty
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.result.ResolvedArtifactResult
import org.gradle.api.invocation.Gradle
/**
* ================================================
......@@ -149,7 +148,8 @@ class DoKitPlugin : Plugin<Project> {
val thirdLibInfo =
ThirdLibInfo(
fileName,
DoKitPluginUtil.fileSize(artifactResult.file, 2)
artifactResult.file.length(),
artifactResult.variant.displayName
)
DoKitExtUtil.THIRD_LIB_INFOS.add(thirdLibInfo)
}
......
......@@ -9,4 +9,4 @@ package com.didichuxing.doraemonkit.plugin
* 修订历史:
* ================================================
*/
data class ThirdLibInfo(val name: String, val fileSize: String? = "0kb")
\ No newline at end of file
data class ThirdLibInfo(val name: String, val fileSize: Long, val variant : String)
\ No newline at end of file
......@@ -407,8 +407,8 @@ class CommTransformer : ClassTransformer {
for (thirdLibInfo in DoKitExtUtil.THIRD_LIB_INFOS) {
add(VarInsnNode(ALOAD, 0))
add(LdcInsnNode(thirdLibInfo.name))
add(LdcInsnNode(thirdLibInfo.fileSize))
add(LdcInsnNode(thirdLibInfo.variant))
add(LdcInsnNode(thirdLibInfo.fileSize.toString()))
add(
MethodInsnNode(
......
......@@ -112,7 +112,7 @@ public class DokitFrescoPostprocessor implements Postprocessor {
return mOriginalPostprocessor.getPostprocessorCacheKey();
}
if (mCacheKey == null) {
mCacheKey = new CacheKeySimple("DokitFrescoPostprocessor");
mCacheKey = new SimpleCacheKey("DokitFrescoPostprocessor");
}
return mCacheKey;
}
......
package com.didichuxing.doraemonkit.kit.crash;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.core.view.ViewCompat;
import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.didichuxing.doraemonkit.R;
import com.didichuxing.doraemonkit.constant.CachesKey;
import com.didichuxing.doraemonkit.datapick.DataPickManager;
import com.didichuxing.doraemonkit.util.CacheUtils;
import com.didichuxing.doraemonkit.util.FileUtil;
import com.didichuxing.doraemonkit.util.ImageUtil;
import com.didichuxing.doraemonkit.util.LogHelper;
import java.io.File;
import java.io.Serializable;
import java.util.Date;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
/**
* Created by wanglikun on 2019-06-12
......@@ -26,12 +38,15 @@ public class CrashCaptureManager implements Thread.UncaughtExceptionHandler {
private final Thread.UncaughtExceptionHandler mDefaultHandler;
private final Handler mHandler;
private Context mContext;
private SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmdd");
private String mFilenamePrefix;
private CrashCaptureManager() {
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
generateFilenamePrefix();
}
private static class Holder {
......@@ -56,6 +71,10 @@ public class CrashCaptureManager implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(final Thread t, final Throwable e) {
//让log和图片统一文件名 每次生成新的文件名
generateFilenamePrefix();
//异步保存崩溃截图在华为emui10.0上会失效 已改成同步
asyncSaveCrashScreenshot();
//保存崩溃信息
CacheUtils.saveObject((Serializable) Log.getStackTraceString(e), getCrashCacheFile());
//保存埋点数据
......@@ -63,7 +82,7 @@ public class CrashCaptureManager implements Thread.UncaughtExceptionHandler {
post(new Runnable() {
@Override
public void run() {
Toast.makeText(mContext, mContext.getString(R.string.dk_crash_capture_tips), Toast.LENGTH_SHORT).show();
ToastUtils.showShort(mContext.getString(R.string.dk_crash_capture_tips));
}
});
postDelay(new Runnable() {
......@@ -93,11 +112,56 @@ public class CrashCaptureManager implements Thread.UncaughtExceptionHandler {
}
private File getCrashCacheFile() {
String fileName = new Date().toString();
return new File(getCrashCacheDir() + File.separator + fileName);
return new File(getCrashCacheDir(), String.format("%s.log", mFilenamePrefix));
}
private File getCrashCacheScreenshotFile(int num) {
return new File(getCrashCacheDir(), String.format("%s_%d.png", mFilenamePrefix, num));
}
public void clearCacheHistory() {
FileUtil.deleteDirectory(getCrashCacheDir());
}
private void generateFilenamePrefix() {
mFilenamePrefix = mDateFormat.format(System.currentTimeMillis());
}
public void asyncSaveCrashScreenshot() {
saveCrashScreenshot();
// AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
// @Override
// public void run() {
// saveCrashScreenshot();
// }
// });
}
public void saveCrashScreenshot() {
try {
Class<?> wmgClass = Class.forName("android.view.WindowManagerGlobal");
Object wmgInstance = wmgClass.getMethod("getInstance").invoke(null);
Method getViewRootNames = wmgClass.getMethod("getViewRootNames");
Method getRootView = wmgClass.getMethod("getRootView", String.class);
String[] rootViewNames = (String[]) getViewRootNames.invoke(wmgInstance);
if (rootViewNames != null) {
for (int i = 0; i < rootViewNames.length; i++) {
View rootView = (View) getRootView.invoke(wmgInstance, rootViewNames[i]);
if (rootView != null) {
if (!ViewCompat.isLaidOut(rootView)) {
Log.d(TAG, "View尚未绘制完成,可能无法成功截取图片");
}
Bitmap bitmap = Bitmap.createBitmap(rootView.getWidth(), rootView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
rootView.draw(canvas);
File output = getCrashCacheScreenshotFile(i);
ImageUtil.bitmap2File(bitmap, 100, output);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package com.didichuxing.doraemonkit.kit.sysinfo;
import android.Manifest;
import android.annotation.TargetApi;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.PhoneUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.didichuxing.doraemonkit.R;
import com.didichuxing.doraemonkit.aop.DokitThirdLibInfo;
import com.didichuxing.doraemonkit.kit.core.BaseFragment;
import com.didichuxing.doraemonkit.okhttp_api.OkHttpWrap;
import com.didichuxing.doraemonkit.util.DeviceUtils;
import com.didichuxing.doraemonkit.util.ExecutorUtil;
import com.didichuxing.doraemonkit.util.PermissionUtil;
import com.didichuxing.doraemonkit.util.UIUtils;
import com.didichuxing.doraemonkit.widget.recyclerview.DividerItemDecoration;
import com.didichuxing.doraemonkit.widget.titlebar.HomeTitleBar;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
/**
* 第三方库信息
......@@ -47,6 +35,7 @@ public class ThirdLibInfoFragment extends BaseFragment {
private RecyclerView mInfoList;
private ThirdLibInfoItemAdapter mInfoItemAdapter;
private EditText mEditText;
private RadioGroup mSortGroup;
@Override
protected int onRequestLayout() {
......@@ -75,17 +64,26 @@ public class ThirdLibInfoFragment extends BaseFragment {
}
});
mEditText = findViewById(R.id.edittext);
TextView mTvSearch = findViewById(R.id.tv_search);
mTvSearch.setOnClickListener(new View.OnClickListener() {
mEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onClick(View v) {
String keyWords = mEditText.getText().toString().trim();
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String keyWords = s.toString().trim();
if (keyWords.isEmpty()) {
initData();
} else {
notifyThirdKeyWordsLibInfos(keyWords);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
......@@ -96,6 +94,14 @@ public class ThirdLibInfoFragment extends BaseFragment {
decoration.setDrawable(getResources().getDrawable(R.drawable.dk_divider));
mInfoList.addItemDecoration(decoration);
mSortGroup = findViewById(R.id.sort_option);
mSortGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
mInfoItemAdapter.setData(sortSysInfoItems(null));
}
});
if (DokitThirdLibInfo.THIRD_LIB_INFOS == null || DokitThirdLibInfo.THIRD_LIB_INFOS.isEmpty()) {
ToastUtils.showShort("检查gradle.properties中的DOKIT_THIRD_LIB_SWITCH值是否为true");
}
......@@ -105,7 +111,7 @@ public class ThirdLibInfoFragment extends BaseFragment {
private void initData() {
List<SysInfoItem> sysInfoItems = new ArrayList<>();
addThirdLibInfos(sysInfoItems);
mInfoItemAdapter.setData(sysInfoItems);
mInfoItemAdapter.setData(sortSysInfoItems(sysInfoItems));
}
//添加所有三方库信息
......@@ -113,34 +119,37 @@ public class ThirdLibInfoFragment extends BaseFragment {
for (Map.Entry<String, String> entry : DokitThirdLibInfo.THIRD_LIB_INFOS.entrySet()) {
sysInfoItems.add(new SysInfoItem(entry.getKey(), entry.getValue()));
}
Collections.sort(sysInfoItems, new Comparator<SysInfoItem>() {
@Override
public int compare(SysInfoItem o1, SysInfoItem o2) {
return o1.name.compareToIgnoreCase(o2.name);
}
});
}
private List<SysInfoItem> sortSysInfoItems(List<SysInfoItem> sysInfoItems) {
List<SysInfoItem> data = sysInfoItems == null ? mInfoItemAdapter.getData() : sysInfoItems;
if (mSortGroup.getCheckedRadioButtonId() == R.id.sort_size) {
Collections.sort(data, new Comparator<SysInfoItem>() {
@Override
public int compare(SysInfoItem o1, SysInfoItem o2) {
return (int) (Long.parseLong(o2.value) - Long.parseLong(o1.value));
}
});
} else {
Collections.sort(data, new Comparator<SysInfoItem>() {
@Override
public int compare(SysInfoItem o1, SysInfoItem o2) {
return o1.name.compareToIgnoreCase(o2.name);
}
});
}
return data;
}
//添加所有三方库信息
private void notifyThirdKeyWordsLibInfos(String keyWords) {
List<SysInfoItem> sysInfoItems = new ArrayList<>();
for (Map.Entry<String, String> entry : DokitThirdLibInfo.THIRD_LIB_INFOS.entrySet()) {
if (entry.getKey().startsWith(keyWords) || entry.getKey().contains(keyWords)) {
if (entry.getKey().toLowerCase().startsWith(keyWords.toLowerCase()) || entry.getKey().toLowerCase().contains(keyWords.toLowerCase())) {
sysInfoItems.add(new SysInfoItem(entry.getKey(), entry.getValue()));
}
}
Collections.sort(sysInfoItems, new Comparator<SysInfoItem>() {
@Override
public int compare(SysInfoItem o1, SysInfoItem o2) {
return o1.name.compareToIgnoreCase(o2.name);
}
});
mInfoItemAdapter.setData(sysInfoItems);
mInfoItemAdapter.setData(sortSysInfoItems(sysInfoItems));
}
......
package com.didichuxing.doraemonkit.kit.sysinfo;
import android.content.Context;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
......@@ -68,7 +69,7 @@ public class ThirdLibInfoItemAdapter extends AbsRecyclerAdapter<AbsViewBinder<Sy
@Override
public void bind(final SysInfoItem sysInfoItem) {
mTvName.setText(sysInfoItem.name);
mTvSize.setText(sysInfoItem.value);
mTvSize.setText(Formatter.formatFileSize(itemView.getContext(), Long.parseLong(sysInfoItem.value)));
}
}
......
......@@ -3,6 +3,11 @@ package com.didichuxing.doraemonkit.util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by wanglikun on 2018/10/30.
*/
......@@ -46,4 +51,19 @@ public class ImageUtil {
}
return bitmap.getPixel(x, y);
}
public static boolean bitmap2File(Bitmap bitmap, int quality, File output) {
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(output));
bitmap.compress(Bitmap.CompressFormat.PNG, quality, bos);
bos.flush();
bos.close();
if (output.exists()){
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
......@@ -21,24 +21,36 @@
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp">
<TextView
android:id="@+id/tv_search"
android:layout_width="wrap_content"
android:layout_height="36dp"
<RadioGroup
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="8dp"
android:gravity="center"
android:text="@string/dk_mock_search"
android:textColor="@color/dk_color_337CC4"
android:textSize="14sp" />
android:layout_centerVertical="true"
android:id="@+id/sort_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:checked="true"
android:id="@+id/sort_name"
style="@style/DK.RadioButton.Left"
android:layout_weight="1"
android:text="@string/dk_third_sort_name" />
<RadioButton
android:id="@+id/sort_size"
style="@style/DK.RadioButton.Right"
android:layout_weight="1"
android:text="@string/dk_third_sort_size" />
</RadioGroup>
<androidx.cardview.widget.CardView
android:id="@+id/cardview"
android:layout_width="match_parent"
android:layout_height="36dp"
android:layout_margin="5dp"
android:layout_toLeftOf="@id/tv_search"
android:layout_toLeftOf="@id/sort_option"
app:cardBackgroundColor="@color/dk_color_FFFFFF"
app:cardCornerRadius="4dp"
app:cardElevation="3dp"
......@@ -48,6 +60,7 @@
app:contentPaddingTop="5dp">
<EditText
android:singleLine="true"
android:id="@+id/edittext"
android:layout_width="match_parent"
android:layout_height="match_parent"
......
......@@ -35,7 +35,7 @@
android:paddingRight="@dimen/dk_dp_15"
android:visibility="gone"
tools:visibility="visible">
<!-- redioGroup-->
<!-- radioGroup-->
<RadioGroup
android:id="@+id/weak_network_option"
android:layout_width="match_parent"
......
......@@ -133,6 +133,9 @@
<string name="dk_item_block_goto_list">View Block History</string>
<string name="dk_item_block_mock">Mock Block</string>
<string name="dk_third_sort_name">By Name</string>
<string name="dk_third_sort_size">By Size</string>
<string name="dk_block_class_has_blocked">blocked %s ms</string>
<string name="dk_block_notification_message">Click for more details</string>
......@@ -145,6 +148,7 @@
<string name="dk_crash_capture_clean_data">Clean Crash Cache</string>
<string name="dk_kit_cache_check_all">all check</string>
<string name="dk_crash_capture_summary_title">Crash Log List</string>
<string name="dk_crash_capture_screenshot">Crash Screenshot Switch</string>
<!--大图检测开关-->
<string name="dk_large_picture_switch">Large image detection switch</string>
......
......@@ -135,6 +135,9 @@
<string name="dk_item_block_goto_list">查看卡顿记录</string>
<string name="dk_item_block_mock">模拟卡顿</string>
<string name="dk_third_sort_name">按名称</string>
<string name="dk_third_sort_size">按大小</string>
<string name="dk_block_class_has_blocked">blocked %s ms</string>
<string name="dk_block_notification_message">Click for more details</string>
......@@ -144,6 +147,7 @@
<string name="dk_crash_capture_look">查看Crash日志</string>
<string name="dk_crash_capture_switch">Crash日志收集开关</string>
<string name="dk_crash_capture_summary_title">Crash日志列表</string>
<string name="dk_crash_capture_screenshot">Crash截图开关</string>
<!--大图检测开关-->
<string name="dk_large_picture_switch">大图检测开关</string>
......
......@@ -133,6 +133,9 @@
<string name="dk_item_block_goto_list">查看 ANR 紀錄</string>
<string name="dk_item_block_mock">模擬 ANR</string>
<string name="dk_third_sort_name">按名稱</string>
<string name="dk_third_sort_size">按大小</string>
<string name="dk_block_class_has_blocked">blocked %s ms</string>
<string name="dk_block_notification_message">Click for more details</string>
......@@ -142,6 +145,7 @@
<string name="dk_crash_capture_look">查看 Crash Log</string>
<string name="dk_crash_capture_switch">Crash Log 收集開關</string>
<string name="dk_crash_capture_summary_title">Crash Log 列表</string>
<string name="dk_crash_capture_screenshot">Crash截圖開關</string>
<!--大图检测开关-->
<string name="dk_large_picture_switch">大圖檢測開關</string>
......
......@@ -149,11 +149,15 @@
<string name="dk_block_class_has_blocked">blocked %s ms</string>
<string name="dk_block_notification_message">Click for more details</string>
<string name="dk_third_sort_name">按名称</string>
<string name="dk_third_sort_size">按大小</string>
<string name="dk_crash_capture_tips">DoraemonKit正在为您记录Crash</string>
<string name="dk_crash_capture_no_record">暂无crash记录</string>
<string name="dk_crash_capture_switch">Crash日志收集开关</string>
<string name="dk_crash_capture_clean_data">一键清理Crash日志</string>
<string name="dk_crash_capture_summary_title">Crash日志列表</string>
<string name="dk_crash_capture_screenshot">Crash截图开关</string>
<string name="dk_crash_need_permission">请授权读写权限,避免crash文件丢失</string>
<string name="dk_weak_network_switch">模拟弱网开关</string>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册