Improved logcat

This commit is contained in:
2dust
2025-01-13 12:50:35 +08:00
parent 0d0da6bfec
commit a4edf86195
5 changed files with 143 additions and 48 deletions

View File

@@ -1,13 +1,13 @@
package com.v2ray.ang.ui
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.method.ScrollingMovementMethod
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.appcompat.widget.SearchView
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.v2ray.ang.AppConfig.ANG_PACKAGE
import com.v2ray.ang.R
import com.v2ray.ang.databinding.ActivityLogcatBinding
@@ -19,9 +19,11 @@ import kotlinx.coroutines.withContext
import java.io.IOException
class LogcatActivity : BaseActivity() {
private val binding by lazy {
ActivityLogcatBinding.inflate(layoutInflater)
}
private val binding by lazy { ActivityLogcatBinding.inflate(layoutInflater) }
var logsetsAll: MutableList<String> = mutableListOf()
var logsets: MutableList<String> = mutableListOf()
private val adapter by lazy { LogcatRecyclerAdapter(this) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -29,24 +31,20 @@ class LogcatActivity : BaseActivity() {
title = getString(R.string.title_logcat)
logcat(false)
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.layoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = adapter
binding.recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
getLogcat()
}
private fun logcat(shouldFlushLog: Boolean) {
private fun getLogcat() {
try {
binding.pbWaiting.visibility = View.VISIBLE
lifecycleScope.launch(Dispatchers.Default) {
if (shouldFlushLog) {
val lst = LinkedHashSet<String>()
lst.add("logcat")
lst.add("-c")
withContext(Dispatchers.IO) {
val process = Runtime.getRuntime().exec(lst.toTypedArray())
process.waitFor()
}
}
val lst = LinkedHashSet<String>()
lst.add("logcat")
lst.add("-d")
@@ -57,15 +55,34 @@ class LogcatActivity : BaseActivity() {
val process = withContext(Dispatchers.IO) {
Runtime.getRuntime().exec(lst.toTypedArray())
}
// val bufferedReader = BufferedReader(
// InputStreamReader(process.inputStream))
// val allText = bufferedReader.use(BufferedReader::readText)
val allText = process.inputStream.bufferedReader().use { it.readText() }
val allText = process.inputStream.bufferedReader().use { it.readLines() }
launch(Dispatchers.Main) {
binding.tvLogcat.text = allText
binding.tvLogcat.movementMethod = ScrollingMovementMethod()
logsetsAll = allText.toMutableList()
logsets = allText.toMutableList()
adapter.notifyDataSetChanged()
binding.pbWaiting.visibility = View.GONE
Handler(Looper.getMainLooper()).post { binding.svLogcat.fullScroll(View.FOCUS_DOWN) }
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}
private fun clearLogcat() {
try {
lifecycleScope.launch(Dispatchers.Default) {
val lst = LinkedHashSet<String>()
lst.add("logcat")
lst.add("-c")
withContext(Dispatchers.IO) {
val process = Runtime.getRuntime().exec(lst.toTypedArray())
process.waitFor()
}
launch(Dispatchers.Main) {
logsetsAll.clear()
logsets.clear()
adapter.notifyDataSetChanged()
}
}
} catch (e: IOException) {
@@ -75,21 +92,51 @@ class LogcatActivity : BaseActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_logcat, menu)
val searchItem = menu.findItem(R.id.search_view)
if (searchItem != null) {
val searchView = searchItem.actionView as SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean = false
override fun onQueryTextChange(newText: String?): Boolean {
filterLogs(newText)
return false
}
})
searchView.setOnCloseListener {
filterLogs("")
false
}
}
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.copy_all -> {
Utils.setClipboard(this, binding.tvLogcat.text.toString())
Utils.setClipboard(this, logsets.joinToString("\n"))
toast(R.string.toast_success)
true
}
R.id.clear_all -> {
logcat(true)
clearLogcat()
true
}
else -> super.onOptionsItemSelected(item)
}
}
private fun filterLogs(content: String?): Boolean {
val key = content?.trim()
logsets = if (key.isNullOrEmpty()) {
logsetsAll.toMutableList()
} else {
logsetsAll.filter { it.contains(key) }.toMutableList()
}
adapter?.notifyDataSetChanged()
return true
}
}

View File

@@ -0,0 +1,31 @@
package com.v2ray.ang.ui
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.v2ray.ang.databinding.ItemRecyclerLogcatBinding
class LogcatRecyclerAdapter(val activity: LogcatActivity) : RecyclerView.Adapter<LogcatRecyclerAdapter.MainViewHolder>() {
private var mActivity: LogcatActivity = activity
override fun getItemCount() = mActivity.logsets.size
override fun onBindViewHolder(holder: MainViewHolder, position: Int) {
val content = mActivity.logsets[position]
holder.itemSubSettingBinding.logContent.text = content
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder {
return MainViewHolder(
ItemRecyclerLogcatBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
class MainViewHolder(val itemSubSettingBinding: ItemRecyclerLogcatBinding) : RecyclerView.ViewHolder(itemSubSettingBinding.root)
}

View File

@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:paddingStart="@dimen/padding_start"
android:paddingEnd="@dimen/padding_end"
tools:context=".ui.LogcatActivity">
<ProgressBar
@@ -16,25 +15,13 @@
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<ScrollView
android:id="@+id/sv_logcat"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:fillViewport="false"
android:foregroundGravity="bottom">
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<TextView
android:id="@+id/tv_logcat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:maxLines="65536"
android:textAppearance="?android:attr/textAppearanceSmall" />
</ScrollView>
</RelativeLayout>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/layout_margin_spacing">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/log_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
</LinearLayout>
</LinearLayout>

View File

@@ -1,14 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search_view"
android:icon="@drawable/ic_outline_filter_alt_24"
android:title="@string/menu_item_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always|collapseActionView" />
<item
android:id="@+id/clear_all"
android:icon="@drawable/ic_delete_24dp"
android:title="@string/logcat_clear"
app:showAsAction="always" />
app:showAsAction="ifRoom" />
<item
android:id="@+id/copy_all"
android:icon="@drawable/ic_copy"
android:title="@string/logcat_copy"
app:showAsAction="always" />
app:showAsAction="ifRoom" />
</menu>