From a4edf86195dcc11049d384d21b384e7841dbf1d6 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Mon, 13 Jan 2025 12:50:35 +0800 Subject: [PATCH] Improved logcat --- .../java/com/v2ray/ang/ui/LogcatActivity.kt | 101 +++++++++++++----- .../com/v2ray/ang/ui/LogcatRecyclerAdapter.kt | 31 ++++++ .../src/main/res/layout/activity_logcat.xml | 25 ++--- .../main/res/layout/item_recycler_logcat.xml | 24 +++++ V2rayNG/app/src/main/res/menu/menu_logcat.xml | 10 +- 5 files changed, 143 insertions(+), 48 deletions(-) create mode 100644 V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatRecyclerAdapter.kt create mode 100644 V2rayNG/app/src/main/res/layout/item_recycler_logcat.xml diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatActivity.kt index c71294eb..cf9f94bd 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatActivity.kt @@ -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 = mutableListOf() + var logsets: MutableList = 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() - lst.add("logcat") - lst.add("-c") - withContext(Dispatchers.IO) { - val process = Runtime.getRuntime().exec(lst.toTypedArray()) - process.waitFor() - } - } val lst = LinkedHashSet() 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() + 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 + } +} \ No newline at end of file diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatRecyclerAdapter.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatRecyclerAdapter.kt new file mode 100644 index 00000000..4a9c35fa --- /dev/null +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatRecyclerAdapter.kt @@ -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() { + 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) + +} diff --git a/V2rayNG/app/src/main/res/layout/activity_logcat.xml b/V2rayNG/app/src/main/res/layout/activity_logcat.xml index 902116dd..56ec614a 100644 --- a/V2rayNG/app/src/main/res/layout/activity_logcat.xml +++ b/V2rayNG/app/src/main/res/layout/activity_logcat.xml @@ -1,11 +1,10 @@ - + android:layout_height="match_parent" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> - - diff --git a/V2rayNG/app/src/main/res/layout/item_recycler_logcat.xml b/V2rayNG/app/src/main/res/layout/item_recycler_logcat.xml new file mode 100644 index 00000000..927a79ed --- /dev/null +++ b/V2rayNG/app/src/main/res/layout/item_recycler_logcat.xml @@ -0,0 +1,24 @@ + + + + + + + + + + \ No newline at end of file diff --git a/V2rayNG/app/src/main/res/menu/menu_logcat.xml b/V2rayNG/app/src/main/res/menu/menu_logcat.xml index 8044bbde..14911e57 100644 --- a/V2rayNG/app/src/main/res/menu/menu_logcat.xml +++ b/V2rayNG/app/src/main/res/menu/menu_logcat.xml @@ -1,14 +1,20 @@ + + app:showAsAction="ifRoom" /> + app:showAsAction="ifRoom" /> \ No newline at end of file