Wbudowany panel do debugowania requestów w aplikacji.
import rip.nerd.kitsunenet.debug.KNETDebugPanel
// Włącz debug panel (tylko w DEBUG)
if (BuildConfig.DEBUG) {
KNETDebugPanel.install(application)
}
// Panel pokazuje się przez shake gesture
// lub programowo:
KNETDebugPanel.show()
val debugInterceptor = KNETDebugPanel.interceptor()
val client = KNETClient.builder()
.apply {
if (BuildConfig.DEBUG) {
addInterceptor(debugInterceptor)
}
}
.build()
// Teraz wszystkie requesty są widoczne w panelu
Wszystkie wykonane requesty z czasem i statusem
Headers, body, timing dla każdego requestu
Ponowne wykonanie requestu
Export do cURL, Postman, HAR
Wyszukiwanie po URL, statusie, body
Statystyki sukcesu, latencji, błędów
KNETDebugPanel.configure {
// Aktywacja
shakeToOpen = true
notificationEnabled = true // Persistent notification
// Limity
maxRequests = 500
maxBodySize = 100_000
// Retencja
clearOnAppRestart = false
// UI
theme = DebugPanelTheme.DARK
position = DebugPanelPosition.BOTTOM_SHEET
}
// Pobierz wszystkie requesty
val requests = KNETDebugPanel.getRequests()
requests.forEach { entry ->
println("${entry.request.method} ${entry.request.url}")
println("Status: ${entry.response?.statusCode}")
println("Time: ${entry.durationMs}ms")
}
// Wyczyść
KNETDebugPanel.clear()
// Export
val har = KNETDebugPanel.exportToHAR()
val curl = KNETDebugPanel.exportToCurl()
val postman = KNETDebugPanel.exportToPostman("My Collection")
// Pływający przycisk debug
KNETDebugPanel.showFloatingButton(activity)
// Lub w Activity
class DebugActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (BuildConfig.DEBUG) {
KNETDebugPanel.attachTo(this)
}
}
}
// Jeśli chcesz własny UI
@Composable
fun MyDebugPanel() {
val requests by KNETDebugPanel.requestsFlow.collectAsState()
LazyColumn {
items(requests) { entry ->
RequestItem(entry)
}
}
}
@Composable
fun RequestItem(entry: DebugEntry) {
Card(Modifier.padding(8.dp)) {
Column(Modifier.padding(16.dp)) {
Row {
StatusBadge(entry.response?.statusCode ?: 0)
Spacer(Modifier.width(8.dp))
Text(entry.request.method)
Spacer(Modifier.width(8.dp))
Text(
entry.request.url.substringAfter("://").take(40),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
Text("${entry.durationMs}ms", style = MaterialTheme.typography.caption)
}
}
}
// Integracja z Facebook Flipper
if (BuildConfig.DEBUG) {
val networkPlugin = NetworkFlipperPlugin()
val client = KNETClient.builder()
.addInterceptor(FlipperOkhttpInterceptor(networkPlugin))
.build()
AndroidFlipperClient.getInstance(context).apply {
addPlugin(networkPlugin)
start()
}
}
Debug Panel nigdy nie powinien być włączony w production - może ujawnić sensitive data.
// Zawsze sprawdzaj BuildConfig
if (BuildConfig.DEBUG) {
KNETDebugPanel.install(application)
}
// Lub użyj proguard do usunięcia w release:
// -assumenosideeffects class rip.nerd.kitsunenet.debug.** { *; }