Skip to content

Commit

Permalink
Merge pull request #3 from ding1dingx/dev
Browse files Browse the repository at this point in the history
feat(logger): Implement a custom logger with configurable log levels
  • Loading branch information
syxc authored Aug 25, 2024
2 parents f0b6c0f + 2a0a736 commit 388916e
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 53 deletions.
9 changes: 9 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# This will strip `Log.v`, `Log.d`, and `Log.i` statements and will leave `Log.w` and `Log.e` statements intact.
#-assumenosideeffects class android.util.Log {
# public static boolean isLoggable(java.lang.String, int);
# public static int v(...);
# public static int d(...);
# public static int i(...);
#}

# JavascriptInterface
-keepattributes *Annotation*
-keepattributes *JavascriptInterface*
-keepclassmembers class * {
Expand Down
21 changes: 14 additions & 7 deletions app/src/main/java/com/ding1ding/jsbridge/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.ding1ding.jsbridge.app

import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.webkit.WebView
Expand All @@ -11,6 +10,7 @@ import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import com.ding1ding.jsbridge.Callback
import com.ding1ding.jsbridge.ConsolePipe
import com.ding1ding.jsbridge.Logger
import com.ding1ding.jsbridge.MessageHandler
import com.ding1ding.jsbridge.WebViewJavascriptBridge
import com.ding1ding.jsbridge.model.Person
Expand All @@ -27,6 +27,13 @@ class MainActivity :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

if (BuildConfig.DEBUG) {
WebViewJavascriptBridge.setLogLevel(Logger.LogLevel.DEBUG)
} else {
WebViewJavascriptBridge.setLogLevel(Logger.LogLevel.ERROR)
}

setupWebView()
setupClickListeners()
}
Expand Down Expand Up @@ -56,7 +63,7 @@ class MainActivity :

override fun onDestroy() {
releaseWebView()
Log.d(TAG, "onDestroy")
Logger.d(TAG) { "onDestroy" }
super.onDestroy()
}

Expand Down Expand Up @@ -93,7 +100,7 @@ class MainActivity :
bridge = WebViewJavascriptBridge.create(this, webView, lifecycle).apply {
consolePipe = object : ConsolePipe {
override fun post(message: String) {
Log.d("[console.log]", message)
Logger.d("[console.log]") { message }
}
}

Expand All @@ -110,17 +117,17 @@ class MainActivity :

private fun createWebViewClient() = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: android.graphics.Bitmap?) {
Log.d(TAG, "onPageStarted")
Logger.d(TAG) { "onPageStarted" }
}

override fun onPageFinished(view: WebView?, url: String?) {
Log.d(TAG, "onPageFinished")
Logger.d(TAG) { "onPageFinished" }
}
}

private fun createDeviceLoadHandler() = object : MessageHandler<Map<String, String>, Any> {
override fun handle(parameter: Map<String, String>): Any {
Log.d(TAG, "DeviceLoadJavascriptSuccess, $parameter")
Logger.d(TAG) { "DeviceLoadJavascriptSuccess, $parameter" }
return mapOf("result" to "Android")
}
}
Expand Down Expand Up @@ -151,7 +158,7 @@ class MainActivity :
Person("Wukong", 23),
object : Callback<Any> {
override fun onResult(result: Any) {
Log.d(TAG, "$handlerName, $result")
Logger.d(TAG) { "$handlerName, $result" }
}
},
)
Expand Down
8 changes: 0 additions & 8 deletions library/consumer-rules.pro
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
# This will strip `Log.v`, `Log.d`, and `Log.i` statements and will leave `Log.w` and `Log.e` statements intact.
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int d(...);
public static int i(...);
}

-keep class java.lang.reflect.** { *; }
-keep class kotlin.reflect.** { *; }
5 changes: 2 additions & 3 deletions library/src/main/java/com/ding1ding/jsbridge/JsonUtils.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.ding1ding.jsbridge

import android.util.Log
import java.math.BigInteger
import java.text.SimpleDateFormat
import java.util.Date
Expand Down Expand Up @@ -31,7 +30,7 @@ object JsonUtils {
field.name to field.get(any)
}.toJsonObject().toString()
} catch (e: Exception) {
Log.e("[JsBridge]", "Failed to serialize object of type ${any::class.java.simpleName}", e)
Logger.e(e) { "Failed to serialize object of type ${any::class.java.simpleName}" }
JSONObject.quote(any.toString())
}
}
Expand Down Expand Up @@ -68,7 +67,7 @@ object JsonUtils {
else -> parseNumber(json)
}
} catch (e: Exception) {
Log.e("[JsBridge]", "Error parsing JSON: $json", e)
Logger.e(e) { "Error parsing JSON: $json" }
json // Return the original string if parsing fails
}

Expand Down
77 changes: 77 additions & 0 deletions library/src/main/java/com/ding1ding/jsbridge/Logger.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.ding1ding.jsbridge

import android.util.Log
import kotlin.math.min

object Logger {
private const val MAX_LOG_LENGTH = 4000
const val DEFAULT_TAG = "WebViewJsBridge"

@Volatile
var logLevel = LogLevel.INFO

enum class LogLevel { VERBOSE, DEBUG, INFO, WARN, ERROR, NONE }

@JvmStatic
inline fun v(tag: String = DEFAULT_TAG, message: () -> String) =
log(LogLevel.VERBOSE, tag, message)

@JvmStatic
inline fun d(tag: String = DEFAULT_TAG, message: () -> String) = log(LogLevel.DEBUG, tag, message)

@JvmStatic
inline fun i(tag: String = DEFAULT_TAG, message: () -> String) = log(LogLevel.INFO, tag, message)

@JvmStatic
inline fun w(tag: String = DEFAULT_TAG, message: () -> String) = log(LogLevel.WARN, tag, message)

@JvmStatic
inline fun e(tag: String = DEFAULT_TAG, message: () -> String) = log(LogLevel.ERROR, tag, message)

@JvmStatic
inline fun e(throwable: Throwable, tag: String = DEFAULT_TAG, message: () -> String = { "" }) {
if (logLevel <= LogLevel.ERROR) {
val fullMessage = buildString {
append(message())
if (isNotEmpty() && message().isNotEmpty()) append(": ")
append(Log.getStackTraceString(throwable))
}
logInternal(Log.ERROR, tag, fullMessage)
}
}

@JvmStatic
inline fun log(level: LogLevel, tag: String = DEFAULT_TAG, message: () -> String) {
if (logLevel <= level) logInternal(level.toAndroidLogLevel(), tag, message())
}

fun logInternal(priority: Int, tag: String, message: String) {
if (message.length < MAX_LOG_LENGTH) {
Log.println(priority, tag, message)
return
}

var i = 0
val length = message.length
while (i < length) {
var newline = message.indexOf('\n', i)
newline = if (newline != -1) newline else length
do {
val end = min(newline, i + MAX_LOG_LENGTH)
val part = message.substring(i, end)
Log.println(priority, tag, part)
i = end
} while (i < newline)
i++
}
}

fun LogLevel.toAndroidLogLevel() = when (this) {
LogLevel.VERBOSE -> Log.VERBOSE
LogLevel.DEBUG -> Log.DEBUG
LogLevel.INFO -> Log.INFO
LogLevel.WARN -> Log.WARN
LogLevel.ERROR -> Log.ERROR
LogLevel.NONE -> Log.ASSERT
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.ding1ding.jsbridge

interface MessageHandler<in InputType, out OutputType> {
fun handle(parameter: InputType): OutputType
interface MessageHandler<in Input, out Output> {
fun handle(parameter: Input): Output
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.ding1ding.jsbridge

import android.util.Log
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import org.json.JSONObject
Expand Down Expand Up @@ -95,7 +94,7 @@ object MessageSerializer {
)
}
} catch (e: Exception) {
Log.e("[JsBridge]", "Error deserializing message: ${e.message}")
Logger.e(e) { "Error deserializing message: ${e.message}" }
ResponseMessage(null, null, null, null, null)
}

Expand Down Expand Up @@ -131,7 +130,7 @@ object MessageSerializer {
constructor.isAccessible = true
constructor.newInstance(*data.values.toTypedArray())
} catch (e: Exception) {
Log.e("[JsBridge]", "Error creating instance of ${clazz.simpleName}: ${e.message}")
Logger.e(e) { "Error creating instance of ${clazz.simpleName}: ${e.message}" }
data
}
}
Expand Down
Loading

0 comments on commit 388916e

Please sign in to comment.