Browse Source
The PR changes the android resources packaging. Now all resources are packed to the android assets (not only fonts). It unblocks usage android URIs to the resources in a WebView or other external resource consumers. Additionally the PR fixes Android Studio Compose Previews work with multiplatform resources: ![](https://private-user-images.githubusercontent.com/3532155/341182790-ef26b667-ad0d-4efd-b7f9-23cff92ab49d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTg4Nzg0MTgsIm5iZiI6MTcxODg3ODExOCwicGF0aCI6Ii8zNTMyMTU1LzM0MTE4Mjc5MC1lZjI2YjY2Ny1hZDBkLTRlZmQtYjdmOS0yM2NmZjkyYWI0OWQucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDYyMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA2MjBUMTAwODM4WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9OTY1MzdhMTAxMjNmZDRhMDA4ZjdjODBjYzg3M2MyNDg0ZTA5OWFkZGZkZjk1ZDUwOWFkZDk3MmQ2YjIzNzJiYiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.xgUAr_2--ZHo6txhdAANRbe8ju2SQ5EACvK96gaGJnY) For a backward compatibility the resources library tries to read resources in java resources if assets were not found. Fixes https://github.com/JetBrains/compose-multiplatform/issues/4877 Fixes https://github.com/JetBrains/compose-multiplatform/issues/4503 Fixes https://github.com/JetBrains/compose-multiplatform/issues/4932 Fixes https://github.com/JetBrains/compose-multiplatform/issues/4476 ## Release Notes ### Features - Resources - Android Studio Preview works with Compose Multiplatform resources now - Compose Multiplatform resources are stored in the android assets now. This fixes such cases as a rendering resource files in WebViews or Media Playerspull/5006/head
Konstantin
5 months ago
committed by
GitHub
25 changed files with 305 additions and 187 deletions
@ -0,0 +1,13 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
|
||||||
|
<application> |
||||||
|
<provider |
||||||
|
android:authorities="${applicationId}.resources.AndroidContextProvider" |
||||||
|
android:name="org.jetbrains.compose.resources.AndroidContextProvider" |
||||||
|
android:exported="false" |
||||||
|
android:enabled="true"> |
||||||
|
</provider> |
||||||
|
</application> |
||||||
|
|
||||||
|
</manifest> |
@ -0,0 +1,81 @@ |
|||||||
|
package org.jetbrains.compose.resources |
||||||
|
|
||||||
|
import android.annotation.SuppressLint |
||||||
|
import android.content.ContentProvider |
||||||
|
import android.content.ContentValues |
||||||
|
import android.content.Context |
||||||
|
import android.content.pm.ProviderInfo |
||||||
|
import android.database.Cursor |
||||||
|
import android.net.Uri |
||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.ui.platform.LocalContext |
||||||
|
import androidx.compose.ui.platform.LocalInspectionMode |
||||||
|
|
||||||
|
internal val androidContext get() = AndroidContextProvider.ANDROID_CONTEXT |
||||||
|
|
||||||
|
/** |
||||||
|
* The function configures the android context |
||||||
|
* to be used for non-composable resource read functions |
||||||
|
* |
||||||
|
* e.g. `Res.readBytes(...)` |
||||||
|
* |
||||||
|
* Example usage: |
||||||
|
* ``` |
||||||
|
* @Preview |
||||||
|
* @Composable |
||||||
|
* fun MyPreviewComponent() { |
||||||
|
* PreviewContextConfigurationEffect() |
||||||
|
* //... |
||||||
|
* } |
||||||
|
* ``` |
||||||
|
*/ |
||||||
|
@ExperimentalResourceApi |
||||||
|
@Composable |
||||||
|
fun PreviewContextConfigurationEffect() { |
||||||
|
if (LocalInspectionMode.current) { |
||||||
|
AndroidContextProvider.ANDROID_CONTEXT = LocalContext.current |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//https://andretietz.com/2017/09/06/autoinitialise-android-library/ |
||||||
|
internal class AndroidContextProvider : ContentProvider() { |
||||||
|
companion object { |
||||||
|
@SuppressLint("StaticFieldLeak") |
||||||
|
var ANDROID_CONTEXT: Context? = null |
||||||
|
} |
||||||
|
|
||||||
|
override fun onCreate(): Boolean { |
||||||
|
ANDROID_CONTEXT = context |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
override fun attachInfo(context: Context, info: ProviderInfo?) { |
||||||
|
if (info == null) { |
||||||
|
throw NullPointerException("AndroidContextProvider ProviderInfo cannot be null.") |
||||||
|
} |
||||||
|
// So if the authorities equal the library internal ones, the developer forgot to set his applicationId |
||||||
|
if ("org.jetbrains.compose.components.resources.resources.AndroidContextProvider" == info.authority) { |
||||||
|
throw IllegalStateException("Incorrect provider authority in manifest. Most likely due to a " |
||||||
|
+ "missing applicationId variable your application\'s build.gradle.") |
||||||
|
} |
||||||
|
|
||||||
|
super.attachInfo(context, info) |
||||||
|
} |
||||||
|
|
||||||
|
override fun query( |
||||||
|
uri: Uri, |
||||||
|
projection: Array<out String>?, |
||||||
|
selection: String?, |
||||||
|
selectionArgs: Array<out String>?, |
||||||
|
sortOrder: String? |
||||||
|
): Cursor? = null |
||||||
|
override fun getType(uri: Uri): String? = null |
||||||
|
override fun insert(uri: Uri, values: ContentValues?): Uri? = null |
||||||
|
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int = 0 |
||||||
|
override fun update( |
||||||
|
uri: Uri, |
||||||
|
values: ContentValues?, |
||||||
|
selection: String?, |
||||||
|
selectionArgs: Array<out String>? |
||||||
|
): Int = 0 |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package org.jetbrains.compose.resources |
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.runtime.ProvidableCompositionLocal |
||||||
|
|
||||||
|
internal actual val ProvidableCompositionLocal<ResourceReader>.currentOrPreview: ResourceReader |
||||||
|
@Composable get() = current |
Loading…
Reference in new issue