Browse Source

feature:zap模块采集日志开发

#Suyghur 4 năm trước cách đây
mục cha
commit
628bf520cb

+ 1 - 0
demo/build.gradle

@@ -75,5 +75,6 @@ dependencies {
 //    implementation project(':library_caps')
     implementation project(':library_zap')
     implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.1"
+    implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
 
 }

+ 12 - 0
demo/src/main/AndroidManifest.xml

@@ -20,6 +20,18 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+
+        <activity
+            android:name=".ZapActivity"
+            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
+            android:exported="true"
+            android:launchMode="singleTask"
+            android:screenOrientation="portrait">
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
     </application>
 
 </manifest>

+ 32 - 2
demo/src/main/java/com/suyghur/dolin/simple/DemoActivity.kt

@@ -1,13 +1,17 @@
 package com.suyghur.dolin.simple
 
 import android.app.Activity
+import android.app.AlertDialog
 import android.os.Bundle
+import android.view.KeyEvent
 import android.view.View
 import android.widget.Button
 import android.widget.LinearLayout
 import com.suyghur.dolin.zap.Zap
 import com.suyghur.dolin.zap.entity.Level
+import com.suyghur.dolin.zap.util.FileUtils
 import com.suyghur.dolin.zap.util.LevelUtils
+import kotlin.system.exitProcess
 
 /**
  * @author #Suyghur.
@@ -16,7 +20,7 @@ import com.suyghur.dolin.zap.util.LevelUtils
 class DemoActivity : Activity(), View.OnClickListener {
 
     private val events: MutableList<Item> = mutableListOf(
-            Item(0, "申请单个危险权限"),
+            Item(0, "Zap日志测试"),
             Item(1, "申请多个危险权限")
     )
 
@@ -36,9 +40,35 @@ class DemoActivity : Activity(), View.OnClickListener {
         setContentView(layout)
     }
 
+    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            AlertDialog.Builder(this)
+                    .setTitle("退出应用")
+                    .setCancelable(false)
+                    .setMessage("是否退出")
+                    .setPositiveButton("确认") { dialog, _ ->
+                        dialog?.dismiss()
+                        finish()
+                    }
+                    .setNegativeButton("取消") { dialog, _ ->
+                        dialog?.dismiss()
+                    }.show()
+            return true
+        }
+        return super.onKeyDown(keyCode, event)
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        Zap.recycle()
+        exitProcess(0)
+    }
+
     override fun onClick(v: View?) {
         v?.apply {
-
+            when (tag as Int) {
+                0 -> ZapActivity.start(this@DemoActivity)
+            }
         }
     }
 }

+ 4 - 2
demo/src/main/java/com/suyghur/dolin/simple/DemoApplication.kt

@@ -2,6 +2,7 @@ package com.suyghur.dolin.simple
 
 import android.app.Application
 import android.content.Context
+import androidx.lifecycle.ProcessLifecycleOwner
 import com.suyghur.dolin.zap.entity.Config
 import com.suyghur.dolin.zap.entity.Level
 import com.suyghur.dolin.zap.Zap
@@ -18,12 +19,13 @@ class DemoApplication : Application() {
 
     override fun onCreate() {
         super.onCreate()
-        val config = Config.Builder(this)
+//        ProcessLifecycleOwner.get().lifecycle.addObserver(MyLifecycleObserver())
+        val config = Config.Builder()
                 .setLogcatLevel(Level.DEBUG)
                 .setRecordEnable(true)
                 .setRecordLevel(Level.DEBUG)
                 .setOverdueDay(3)
                 .create()
-        Zap.initialize(config)
+        Zap.initialize(this, config)
     }
 }

+ 35 - 1
demo/src/main/java/com/suyghur/dolin/simple/MyLifecycleObserver.kt

@@ -1,10 +1,44 @@
 package com.suyghur.dolin.simple
 
+import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleObserver
+import androidx.lifecycle.OnLifecycleEvent
+import com.suyghur.dolin.zap.Zap
 
 /**
  * @author #Suyghur.
  * Created on 4/8/21
  */
-class MyLifecycleObserver: LifecycleObserver {
+class MyLifecycleObserver : LifecycleObserver {
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
+    fun onCreate() {
+        Zap.d("Application onCreate")
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_START)
+    fun onStart() {
+        Zap.d("Application onStart")
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
+    fun onResume() {
+        Zap.d("Application onResume")
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
+    fun onPause() {
+        Zap.d("Application onPause")
+    }
+
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+    fun onStop() {
+        Zap.d("Application onStop")
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+    fun onDestroy() {
+        Zap.d("Application onDestroy")
+    }
 }

+ 49 - 0
demo/src/main/java/com/suyghur/dolin/simple/ZapActivity.kt

@@ -0,0 +1,49 @@
+package com.suyghur.dolin.simple
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.widget.Button
+import android.widget.LinearLayout
+import com.suyghur.dolin.zap.Zap
+import com.suyghur.dolin.zap.util.FileUtils
+
+/**
+ * @author #Suyghur.
+ * Created on 4/9/21
+ */
+class ZapActivity : Activity(), View.OnClickListener {
+
+    private val events: MutableList<Item> = mutableListOf(
+            Item(0, "DEBUG日志"),
+            Item(1, "INFO日志"),
+            Item(2, "WARNING日志"),
+            Item(3, "ERROR日志"),
+    )
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        val layout = LinearLayout(this)
+        layout.orientation = LinearLayout.VERTICAL
+        for (event in events) {
+            with(Button(this)) {
+                tag = event.id
+                text = event.text
+                setOnClickListener(this@ZapActivity)
+                layout.addView(this)
+            }
+        }
+        setContentView(layout)
+        Zap.d(FileUtils.getLogDir(this))
+    }
+
+    override fun onClick(v: View?) {
+    }
+
+    companion object {
+        fun start(activity: Activity) {
+            activity.startActivity(Intent(activity, ZapActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
+        }
+    }
+}

+ 1 - 1
demo/src/main/res/values/strings.xml

@@ -1,3 +1,3 @@
 <resources>
-    <string name="app_name">Zege</string>
+    <string name="app_name">Dolin</string>
 </resources>

+ 2 - 0
library_zap/build.gradle

@@ -56,6 +56,8 @@ dependencies {
     implementation "org.jetbrains.kotlin:kotlin-stdlib:$KOTLIN_VERSION"
     implementation 'androidx.core:core-ktx:1.3.2'
 //    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.1"
+//    implementation "androidx.lifecycle:lifecycle-extensions-ktx:1.0.1"
     implementation 'androidx.fragment:fragment-ktx:1.3.2'
+    implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
 
 }

+ 1 - 1
library_zap/src/main/cpp/buffer.cpp

@@ -99,7 +99,7 @@ void Buffer::callFileFlush() {
 }
 
 void Buffer::callFileFlush(FileFlush *flush) {
-    callFileFlush(file_flush_ptr, nullptr);
+    callFileFlush(flush, nullptr);
 }
 
 void Buffer::callFileFlush(FileFlush *flush, Buffer *buffer) {

+ 6 - 2
library_zap/src/main/java/com/suyghur/dolin/zap/Zap.kt

@@ -10,8 +10,12 @@ import com.suyghur.dolin.zap.impl.ZapPrintImpl
  */
 object Zap {
 
-    fun initialize(application: Application,config: Config) {
-        ZapPrintImpl.getInstance().initialize(application,config)
+    fun initialize(application: Application, config: Config) {
+        ZapPrintImpl.getInstance().initialize(application, config)
+    }
+
+    fun recycle() {
+        ZapPrintImpl.getInstance().recycle()
     }
 
     fun d(any: Any?) {

+ 8 - 0
library_zap/src/main/java/com/suyghur/dolin/zap/entity/ZapData.kt

@@ -25,6 +25,14 @@ class ZapData {
         }
     }
 
+    override fun toString(): String {
+        return "ZapData{" +
+                "level=" + level.name +
+                ", tag='" + tag + '\'' +
+                ", msg='" + msg + '\'' +
+                '}'
+    }
+
     companion object {
         private val sPoolSync = Any()
         private var sPool: ZapData? = null

+ 1 - 1
library_zap/src/main/java/com/suyghur/dolin/zap/impl/DateFileFormatter.kt

@@ -36,7 +36,7 @@ class DateFileFormatter : IFormatter {
         if (stringBuilder.length > timeLength) {
             stringBuilder.delete(timeLength, stringBuilder.length)
         }
-        return stringBuilder.append("[${LevelUtils.getShortLevelName(level)}").append(tag).append(": ").append(msg).append("\n").toString()
+        return stringBuilder.append("[${LevelUtils.getShortLevelName(level)}]").append(tag).append(": ").append(msg).append("\n").toString()
     }
 
     override fun format(level: Level, tag: String, msg: String): String {

+ 2 - 0
library_zap/src/main/java/com/suyghur/dolin/zap/impl/Record2MMap.kt

@@ -1,5 +1,6 @@
 package com.suyghur.dolin.zap.impl
 
+import com.suyghur.dolin.zap.Zap
 import com.suyghur.dolin.zap.internal.IRecord
 
 /**
@@ -33,6 +34,7 @@ class Record2MMap(bufferPath: String, capacity: Int, logPath: String, compress:
     override fun asyncFlush() {
         if (ptr != 0L) {
             try {
+                Zap.d("asyncFlush")
                 asyncFlushNative(ptr)
             } catch (e: Exception) {
                 e.printStackTrace()

+ 35 - 32
library_zap/src/main/java/com/suyghur/dolin/zap/impl/ZapLifecycle.kt

@@ -4,51 +4,54 @@ import android.app.Activity
 import android.app.Application
 import android.os.Bundle
 
+
 /**
  * @author #Suyghur.
  * Created on 4/8/21
  */
 object ZapLifecycle {
 
-    fun registerZapLifeCallback(application: Application, record2MMap: Record2MMap) {
-        application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
-            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
-            }
+    private var record2MMap: Record2MMap? = null
+    private var application: Application? = null
 
-            override fun onActivityStarted(activity: Activity) {
-            }
+    private val callback = object : Application.ActivityLifecycleCallbacks {
+        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
+        }
 
-            override fun onActivityResumed(activity: Activity) {
-            }
+        override fun onActivityStarted(activity: Activity) {
+        }
 
-            override fun onActivityPaused(activity: Activity) {
-                record2MMap.asyncFlush()
-            }
+        override fun onActivityResumed(activity: Activity) {
+        }
 
-            override fun onActivityStopped(activity: Activity) {
-            }
+        override fun onActivityPaused(activity: Activity) {
+            record2MMap?.asyncFlush()
+        }
 
-            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
-                record2MMap.asyncFlush()
-            }
+        override fun onActivityStopped(activity: Activity) {
+        }
 
-            override fun onActivityDestroyed(activity: Activity) {
-                record2MMap.asyncFlush()
-            }
+        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
+        }
 
-        })
+        override fun onActivityDestroyed(activity: Activity) {
+        }
     }
 
-//    private fun initFragmentLifeCallback(): FragmentManager.FragmentLifecycleCallbacks {
-//        return object : FragmentManager.FragmentLifecycleCallbacks() {
-//            override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
-//                super.onFragmentCreated(fm, f, savedInstanceState)
-//            }
-//
-//            override fun onFragmentResumed(fm: FragmentManager, f: Fragment) {
-//                super.onFragmentResumed(fm, f)
-//            }
-//
-//        }
-//    }
+    fun registerZapLifeCallback(application: Application, record2MMap: Record2MMap) {
+        this.application = application
+        this.record2MMap = record2MMap
+        application.registerActivityLifecycleCallbacks(callback)
+    }
+
+    fun unregisterZapLifeCallback() {
+        application?.apply {
+            unregisterActivityLifecycleCallbacks(callback)
+            application = null
+        }
+        record2MMap?.apply {
+            record2MMap = null
+        }
+
+    }
 }

+ 18 - 3
library_zap/src/main/java/com/suyghur/dolin/zap/impl/ZapPrintImpl.kt

@@ -4,11 +4,16 @@ import android.app.Application
 import android.text.TextUtils
 import android.util.Log
 import androidx.annotation.Keep
+import androidx.lifecycle.ProcessLifecycleOwner
 import com.suyghur.dolin.zap.entity.Config
 import com.suyghur.dolin.zap.entity.Level
 import com.suyghur.dolin.zap.entity.ZapData
 import com.suyghur.dolin.zap.internal.ILogger
+import com.suyghur.dolin.zap.util.FileUtils
+import java.io.File
 import java.lang.reflect.Array
+import java.text.SimpleDateFormat
+import java.util.*
 
 /**
  * @author #Suyghur.
@@ -30,7 +35,7 @@ class ZapPrintImpl : ILogger {
         }
 
         logDir = if (TextUtils.isEmpty(config.logDir)) {
-            application.getExternalFilesDir("dolin/zap")!!.absolutePath
+            FileUtils.getLogDir(application)
         } else {
             config.logDir
         }
@@ -38,12 +43,21 @@ class ZapPrintImpl : ILogger {
         this.tag = config.defaultTag
         this.logcatLevel = config.logcatLevel
         this.recordLevel = config.recordLevel
+        val logFileName = logDir + File.separator + SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date()) + "-zap"
         if (config.recordEnable) {
-            record2MMap = Record2MMap(config.logDir, 1, "", false)
+            record2MMap = Record2MMap("$logDir/zap.cache", 1024 * 400, logFileName, false)
             ZapLifecycle.registerZapLifeCallback(application, record2MMap!!)
         }
     }
 
+    fun recycle() {
+        record2MMap?.apply {
+            ZapLifecycle.unregisterZapLifeCallback()
+            asyncFlush()
+            release()
+        }
+    }
+
     override fun d(any: Any?) {
         d(tag, any)
     }
@@ -85,7 +99,7 @@ class ZapPrintImpl : ILogger {
     }
 
     private fun interceptRecord(level: Level): Boolean {
-        return level.ordinal >= recordLevel.ordinal
+        return level.ordinal < recordLevel.ordinal
     }
 
     private fun print(level: Level, tag: String, any: Any?) {
@@ -145,6 +159,7 @@ class ZapPrintImpl : ILogger {
     }
 
     private fun doRecord(data: ZapData) {
+        Log.d("dolin_zap", "$data")
         record2MMap?.write(dateFileFormatter.format(data.level, data.tag, data.msg))
     }
 

+ 23 - 0
library_zap/src/main/java/com/suyghur/dolin/zap/util/FileUtils.kt

@@ -0,0 +1,23 @@
+package com.suyghur.dolin.zap.util
+
+import android.content.Context
+import java.io.File
+
+/**
+ * @author #Suyghur.
+ * Created on 4/9/21
+ */
+object FileUtils {
+
+    fun getLogDir(context: Context): String {
+        var path = context.getExternalFilesDir("dolin/zap")
+        if (path == null) {
+            path = File(context.filesDir, "dolin/zap")
+        }
+        if (!path.exists()) {
+            path.mkdirs()
+        }
+        return path.absolutePath
+
+    }
+}