parent
a282b3e72e
commit
cb83bc0ee7
@ -0,0 +1,35 @@
|
||||
plugins {
|
||||
id("com.android.library")
|
||||
kotlin("android")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.mylibrary"
|
||||
compileSdk = 33
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 21
|
||||
targetSdk = 33
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.app.videolibrary)
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
# In your library's consumer-proguard-rules.pro
|
||||
-keep, allowoptimization class * implements com.example.mylibrary.MyWorker {
|
||||
<init>();
|
||||
}
|
||||
|
||||
-keepattributes *Annotation*
|
||||
|
||||
-keep @interface com.example.mylibrary.OnEvent
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
@com.example.mylibrary.OnEvent <methods>;
|
||||
}
|
||||
|
||||
-keep @interface com.example.mylibrary.ReflectiveExecutor
|
||||
|
||||
-keep @com.example.mylibrary.ReflectiveExecutor class *{
|
||||
# Keep the public, no-argument constructor so that an instance of the class can be created.
|
||||
# <init> is the internal name for a constructor.
|
||||
public <init>();
|
||||
|
||||
# Keep the public execute() method that has no parameters.
|
||||
# This is critical because TaskRunner calls getMethod("execute").
|
||||
# If this method is renamed (obfuscated) or removed (shrunk), your app will crash.
|
||||
public void execute();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
@ -0,0 +1,24 @@
|
||||
package com.example.mylibrary
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.example.mylibrary.test", appContext.packageName)
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.mylibrary
|
||||
|
||||
import android.util.Log
|
||||
import kotlin.annotation.AnnotationRetention.RUNTIME
|
||||
|
||||
// In your library:
|
||||
@Retention(RUNTIME)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class OnEvent
|
||||
|
||||
class EventBus {
|
||||
fun dispatch(listener: Any) {
|
||||
Log.e("EventBus", "Dispatching event to $listener")
|
||||
// Find all methods annotated with @OnEvent and invoke them
|
||||
listener::class.java.declaredMethods.forEach { method ->
|
||||
if (method.isAnnotationPresent(OnEvent::class.java)) {
|
||||
try {
|
||||
method.invoke(listener)
|
||||
} catch (e: Exception) { /* ... */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.mylibrary
|
||||
|
||||
import android.util.Log
|
||||
|
||||
/**
|
||||
* This annotation is now targeted at classes.
|
||||
*/
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class ReflectiveExecutor
|
||||
|
||||
class TaskRunner {
|
||||
fun process(task: Any) {
|
||||
Log.e("R8","TaskRunner processing " + task.toString())
|
||||
// Get the Java Class object for the instance
|
||||
val taskClass = task::class.java
|
||||
// 1. Check if the CLASS is annotated with @ReflectiveExecutor
|
||||
if (taskClass.isAnnotationPresent(ReflectiveExecutor::class.java)) {
|
||||
// 2. If it's annotated, we assume a contract: the class must have a public method named "execute".
|
||||
// We use getMethod() to find that specific method.
|
||||
val methodToCall = taskClass.getMethod("execute") // Throws an exception if not found
|
||||
|
||||
// 3. Invoke the "execute" method on the provided 'task' instance.
|
||||
methodToCall.invoke(task)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.mylibrary
|
||||
|
||||
|
||||
|
||||
// This is an example of loading a class by name and running its doWork method.
|
||||
|
||||
interface MyWorker {
|
||||
fun doWork()
|
||||
}
|
||||
|
||||
object WorkerLoader {
|
||||
fun loadAndRun(className: String) {
|
||||
val workerClass = Class.forName(className)
|
||||
val worker = workerClass.getDeclaredConstructor().newInstance() as MyWorker
|
||||
worker.doWork()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package com.example.mylibrary
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
plugins {
|
||||
id("com.android.library")
|
||||
kotlin("android")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.videolibrary"
|
||||
compileSdk = 33
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 21
|
||||
targetSdk = 33
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.example.analytics.video
|
||||
|
||||
class VideoEventTracker {
|
||||
// This constructor must be kept for the reflection call to succeed.
|
||||
init { /* ... */ }
|
||||
}
|
Loading…
Reference in new issue