运行时使用 appcompat 覆盖 android

Esl*_*ein 5 android overlay rro oms

我想为使用 appcompat 的应用程序制作运行时覆盖,但我无法让它工作。

\n

我按照这个例子

\n

首先:\n我创建了我想要覆盖的 Android 应用程序。我正在尝试将文本视图“Hello World”中的字符串覆盖为“Hello World override!”

\n

应用程序代码快照

\n

主要活动:

\n
class MainActivity : AppCompatActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

主要活动布局:

\n
<?xml version="1.0" encoding="utf-8"?>\n<FrameLayout\n\xc2\xa0xmlns:android="http://schemas.android.com/apk/res/android"\n\xc2\xa0xmlns:app="http://schemas.android.com/apk/res-auto"\n\xc2\xa0xmlns:tools="http://schemas.android.com/tools"\n\xc2\xa0android:layout_width="match_parent"\n\xc2\xa0android:layout_height="match_parent"\n\xc2\xa0tools:context=".MainActivity">\n\n\xc2\xa0<TextView\n\xc2\xa0android:layout_width="wrap_content"\n\xc2\xa0android:layout_height="wrap_content"\n\xc2\xa0android:text="@string/hello_world"\n\xc2\xa0/>\n\n</FrameLayout>\n
Run Code Online (Sandbox Code Playgroud)\n

显现:

\n
<?xml version="1.0" encoding="utf-8"?>\n<manifest xmlns:android="http://schemas.android.com/apk/res/android"\n\xc2\xa0xmlns:tools="http://schemas.android.com/tools"\n\xc2\xa0package="com.example.app">\n\n\xc2\xa0<application\n\xc2\xa0 \xc2\xa0 \xc2\xa0android:allowBackup="true"\n\xc2\xa0 \xc2\xa0 \xc2\xa0android:icon="@mipmap/ic_launcher"\n\xc2\xa0 \xc2\xa0 \xc2\xa0android:label="@string/app_name"\n\xc2\xa0 \xc2\xa0 \xc2\xa0android:roundIcon="@mipmap/ic_launcher_round"\n     android:theme="@style/MyTheme"\n\xc2\xa0 \xc2\xa0 \xc2\xa0android:supportsRtl="true">\n\xc2\xa0 \xc2\xa0 \xc2\xa0<activity android:name=".MainActivity">\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0<intent-filter>\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0<action android:name="android.intent.action.MAIN"/>\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0<category android:name="android.intent.category.LAUNCHER"/>\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0</intent-filter>\n\xc2\xa0 \xc2\xa0 \xc2\xa0</activity>\n\xc2\xa0</application>\n\n</manifest>\n
Run Code Online (Sandbox Code Playgroud)\n

应用主题:

\n
\n    <style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar">\n        <!-- Customize your theme here. -->\n        <item name="colorPrimary">@color/colorPrimary</item>\n        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>\n        <item name="colorAccent">@color/colorAccent</item>\n    </style>\n\n
Run Code Online (Sandbox Code Playgroud)\n

字符串资源

\n
    <string name="hello_world">Hello World!</string>\n
Run Code Online (Sandbox Code Playgroud)\n

到目前为止,代码运行良好:)

\n

然后我创建包含覆盖资源的覆盖项目。

\n

Overlay项目代码截图:

\n

显现:

\n
<manifest xmlns:android="http://schemas.android.com/apk/res/android"\n          package="com.example.overlay">\n\n    <overlay\n        android:priority="1"\n        android:targetPackage="com.example.app"/>\n    <application android:hasCode="false"/>\n\n</manifest>\n
Run Code Online (Sandbox Code Playgroud)\n

我想在运行时覆盖它们的字符串资源

\n
    <string name="hello_world">Hello World Overlay!</string>\n
Run Code Online (Sandbox Code Playgroud)\n

我构建并安装了 apk。当我使用时我可以找到它作为覆盖 adb shell cmd overlay list

\n

一旦我启用了覆盖,adb shell cmd overlay enable --user 0 com.example.overlay我就遇到了这个崩溃。

\n
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.MainActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)\n        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5279)\n        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5187)\n        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)\n        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)\n        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)\n        at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:57)\n        at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5238)\n        at android.app.ActivityThread.access$3400(ActivityThread.java:219)\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2026)\n        at android.os.Handler.dispatchMessage(Handler.java:107)\n        at android.os.Looper.loop(Looper.java:214)\n        at android.app.ActivityThread.main(ActivityThread.java:7356)\n        at java.lang.reflect.Method.invoke(Native Method)\n        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)\n     Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.\n        at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:696)\n        at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659)\n        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:552)\n        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161)\n        at com.example.app.MainActivity.onCreate(MainActivity.kt:9)\n        at android.app.Activity.performCreate(Activity.java:7802)\n        at android.app.Activity.performCreate(Activity.java:7791)\n        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)\n        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)\n        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)\xc2\xa0\n        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5279)\xc2\xa0\n        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5187)\xc2\xa0\n        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)\xc2\xa0\n        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)\xc2\xa0\n        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)\xc2\xa0\n        at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:57)\xc2\xa0\n        at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5238)\xc2\xa0\n        at android.app.ActivityThread.access$3400(ActivityThread.java:219)\xc2\xa0\n        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2026)\xc2\xa0\n        at android.os.Handler.dispatchMessage(Handler.java:107)\xc2\xa0\n        at android.os.Looper.loop(Looper.java:214)\xc2\xa0\n        at android.app.ActivityThread.main(ActivityThread.java:7356)\xc2\xa0\n        at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)\xc2\xa0\n        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n

但是,我在应用程序和覆盖层上使用 appcompat 主题。

\n

有什么想法可以让它发挥作用吗?

\n

注意:我尝试在 Android 9 和 Android 10 上运行它

\n

更新 1:\n当我从 Activity 而不是 AppCompatActivity 扩展时,它工作正常,没有任何问题

\n

Gk *_*mon -2

您可以在那里使用我的库,我尝试以一种非常可重用的方式做到这一点,以便您可以使用更少的代码进行覆盖。这是有关如何在JavaKotlin中使用它的文档。首先,从要显示水印的活动中初始化它 -

AppWaterMarkBuilder.doConfigure()
                .setAppCompatActivity(MainActivity.this)
                .setWatermarkProperty(R.layout.layout_water_mark)
                .showWatermarkAfterConfig();
Run Code Online (Sandbox Code Playgroud)

然后您可以从应用程序中的任何位置隐藏和显示它 -

  /* For hiding the watermark*/
  AppWaterMarkBuilder.hideWatermark() 

  /* For showing the watermark*/
  AppWaterMarkBuilder.showWatermark() 
Run Code Online (Sandbox Code Playgroud)

动图 -

预览