From c9a1c5bc440722db4bad6c38220f67213caf82c6 Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 16:04:30 -0600 Subject: [PATCH 01/11] Integration of kotlin, Updated Android Dependencies - build.gradle: added sourceSets to handle kotlin, upgraded SdkVersion, and added dependency for kotlin-stdlib - gradle-wrapper.properties: Upgrade gradle from 5.1.1 to 5.6.2 - gradle.properties: Added android.useAndroidX and enableJetifier. --- .../shared_preferences/android/build.gradle | 15 +++++++++++++-- .../shared_preferences/android/gradle.properties | 2 ++ .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../example/android/app/build.gradle | 6 ++++-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/android/build.gradle b/packages/shared_preferences/shared_preferences/android/build.gradle index 8ba16e9dd900..76cce7f135d1 100644 --- a/packages/shared_preferences/shared_preferences/android/build.gradle +++ b/packages/shared_preferences/shared_preferences/android/build.gradle @@ -2,13 +2,15 @@ group 'io.flutter.plugins.sharedpreferences' version '1.0-SNAPSHOT' buildscript { + ext.kotlin_version = '1.3.50' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -28,9 +30,14 @@ allprojects { } apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' android { - compileSdkVersion 28 + compileSdkVersion 29 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } defaultConfig { minSdkVersion 16 @@ -40,3 +47,7 @@ android { disable 'InvalidPackage' } } + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences/android/gradle.properties b/packages/shared_preferences/shared_preferences/android/gradle.properties index 8bd86f680510..4d3226abc21b 100644 --- a/packages/shared_preferences/shared_preferences/android/gradle.properties +++ b/packages/shared_preferences/shared_preferences/android/gradle.properties @@ -1 +1,3 @@ org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences/android/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences/android/gradle/wrapper/gradle-wrapper.properties index caf54fa2801c..01a286e96a21 100644 --- a/packages/shared_preferences/shared_preferences/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/shared_preferences/shared_preferences/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/packages/shared_preferences/shared_preferences/example/android/app/build.gradle b/packages/shared_preferences/shared_preferences/example/android/app/build.gradle index 7a285ba704ab..50753e9fe663 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/build.gradle +++ b/packages/shared_preferences/shared_preferences/example/android/app/build.gradle @@ -22,10 +22,11 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 29 lintOptions { disable 'InvalidPackage' @@ -34,7 +35,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.sharedpreferencesexample" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -54,6 +55,7 @@ flutter { } dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' diff --git a/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties index d757f3d33fcc..01a286e96a21 100644 --- a/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/shared_preferences/shared_preferences/example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip From 470a1c14798e9f301e47ccdad1e3e0661dc2a14e Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 16:06:47 -0600 Subject: [PATCH 02/11] Removed 2nd FlutterActivity from Manifest Due to flutter now is capable to handle flutter activities more efficiently, there's no need to have 2 FlutterActivities --- .../example/android/app/src/main/AndroidManifest.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/AndroidManifest.xml b/packages/shared_preferences/shared_preferences/example/android/app/src/main/AndroidManifest.xml index 04a642a4c748..6d67120f798f 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/AndroidManifest.xml +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/AndroidManifest.xml @@ -10,12 +10,6 @@ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> - - From 0a9b4c900bac95432dca41518386e1723f43bec8 Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 16:07:21 -0600 Subject: [PATCH 03/11] Updated repositories inside pubspec.yaml --- packages/shared_preferences/shared_preferences/pubspec.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 91404eced74d..aebd0a038671 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -45,8 +45,8 @@ dev_dependencies: test: any integration_test: path: ../../integration_test - pedantic: ^1.8.0 + pedantic: ^1.9.2 environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + sdk: ">=2.7.0 <3.0.0" + flutter: ">=1.20.0 <2.0.0" From 70bf170bd3e047d4f7648fc0a01327d791aed9fb Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 16:08:30 -0600 Subject: [PATCH 04/11] Added kotlin to example folder Created kotlin managment inside example/android/build.gradle --- .../shared_preferences/example/android/build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/shared_preferences/shared_preferences/example/android/build.gradle b/packages/shared_preferences/shared_preferences/example/android/build.gradle index 54cc96612793..3100ad2d5553 100644 --- a/packages/shared_preferences/shared_preferences/example/android/build.gradle +++ b/packages/shared_preferences/shared_preferences/example/android/build.gradle @@ -1,11 +1,13 @@ buildscript { + ext.kotlin_version = '1.3.50' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } From 1d0e1ba8cb4efdee771a881a0aa56faaf577f31e Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 16:09:50 -0600 Subject: [PATCH 05/11] Replaced SharedPreferencesPlugin.java SharedPreferencesPlugin.java has been replaced with SharedPreferencesPlugin.kt --- .../SharedPreferencesPlugin.java | 43 ------------------- .../SharedPreferencesPlugin.kt | 32 ++++++++++++++ 2 files changed, 32 insertions(+), 43 deletions(-) delete mode 100644 packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java create mode 100644 packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java b/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java deleted file mode 100644 index be627f3ce613..000000000000 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.sharedpreferences; - -import android.content.Context; -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodChannel; - -/** SharedPreferencesPlugin */ -public class SharedPreferencesPlugin implements FlutterPlugin { - private static final String CHANNEL_NAME = "plugins.flutter.io/shared_preferences"; - private MethodChannel channel; - - @SuppressWarnings("deprecation") - public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { - final SharedPreferencesPlugin plugin = new SharedPreferencesPlugin(); - plugin.setupChannel(registrar.messenger(), registrar.context()); - } - - @Override - public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) { - setupChannel(binding.getBinaryMessenger(), binding.getApplicationContext()); - } - - @Override - public void onDetachedFromEngine(FlutterPlugin.FlutterPluginBinding binding) { - teardownChannel(); - } - - private void setupChannel(BinaryMessenger messenger, Context context) { - channel = new MethodChannel(messenger, CHANNEL_NAME); - MethodCallHandlerImpl handler = new MethodCallHandlerImpl(context); - channel.setMethodCallHandler(handler); - } - - private void teardownChannel() { - channel.setMethodCallHandler(null); - channel = null; - } -} diff --git a/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt b/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt new file mode 100644 index 000000000000..6c8e86f5307e --- /dev/null +++ b/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.kt @@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +package io.flutter.plugins.sharedpreferences +import android.content.Context +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MethodChannel +/** SharedPreferencesPlugin */ +class SharedPreferencesPlugin:FlutterPlugin { + private var channel:MethodChannel? = null + private val CHANNEL_NAME = "plugins.flutter.io/shared_preferences" + fun registerWith(registrar:io.flutter.plugin.common.PluginRegistry.Registrar) { + setupChannel(registrar.messenger(), registrar.context()) + } + override fun onAttachedToEngine(binding:FlutterPlugin.FlutterPluginBinding) { + setupChannel(binding.binaryMessenger, binding.applicationContext) + } + override fun onDetachedFromEngine(binding:FlutterPlugin.FlutterPluginBinding) { + teardownChannel() + } + private fun setupChannel(messenger:BinaryMessenger, context:Context) { + channel = MethodChannel(messenger, CHANNEL_NAME) + channel?.setMethodCallHandler(MethodCallHandlerImpl(context)) + } + private fun teardownChannel() { + channel?.let{ + it.setMethodCallHandler(null) + channel = null + } + } +} \ No newline at end of file From d02d0d57b3c961c1299dfe26029812877ee23679 Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 16:11:27 -0600 Subject: [PATCH 06/11] Moved files Files are moved from java folder into kotlin folder --- .../plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java | 0 .../plugins/sharedpreferencesexample/FlutterActivityTest.java | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename packages/shared_preferences/shared_preferences/example/android/app/src/main/{java => kotlin}/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java (100%) rename packages/shared_preferences/shared_preferences/example/android/app/src/main/{java => kotlin}/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java (100%) diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java similarity index 100% rename from packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java rename to packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1ActivityTest.java diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java similarity index 100% rename from packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java rename to packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/sharedpreferencesexample/FlutterActivityTest.java From 1126d094112bbab4c10cc3f130aec52587c28d71 Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 16:15:41 -0600 Subject: [PATCH 07/11] Change EmbeddingV1Activity - EmbeddingV1Activity has been replaced with EmbeddingV1Activity.kt - For a reason the application of registrarFor isn't recognized by kotlin even when the import has been applied, however everything works perfectly --- .../EmbeddingV1Activity.kt} | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) rename packages/shared_preferences/shared_preferences/example/android/app/src/main/{java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java => kotlin/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.kt} (61%) diff --git a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java b/packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.kt similarity index 61% rename from packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java rename to packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.kt index 3857aea6ce6b..d7c562e79481 100644 --- a/packages/shared_preferences/shared_preferences/example/android/app/src/main/java/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.java +++ b/packages/shared_preferences/shared_preferences/example/android/app/src/main/kotlin/io/flutter/plugins/sharedpreferencesexample/EmbeddingV1Activity.kt @@ -5,18 +5,19 @@ package io.flutter.plugins.sharedpreferencesexample; import android.os.Bundle; +import io.flutter.embedding.android.FlutterActivity +import io.flutter.plugin.common.PluginRegistry.Registrar import dev.flutter.plugins.integration_test.IntegrationTestPlugin; import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin; @SuppressWarnings("deprecation") -public class EmbeddingV1Activity extends io.flutter.app.FlutterActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { +class EmbeddingV1Activity : FlutterActivity() { + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); - IntegrationTestPlugin.registerWith( + /// TODO: CHECK WHY THE ACTIVITY WON'T RECOGNIZE THE METHOD registrarFor, it works as planned without those 2 sections. + /*IntegrationTestPlugin.registerWith( registrarFor("dev.flutter.plugins.integration_test.IntegrationTestPlugin")); SharedPreferencesPlugin.registerWith( - registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin")); + registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin"));*/ } -} +} \ No newline at end of file From c3c55a6042f46cb7b8e4c3cfc6b7a9af71ccd046 Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 16:17:56 -0600 Subject: [PATCH 08/11] Just added public to MethodCallHandlerImpl --- .../plugins/sharedpreferences/MethodCallHandlerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename packages/shared_preferences/shared_preferences/android/src/main/{java => kotlin}/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java (98%) diff --git a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java similarity index 98% rename from packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java rename to packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java index 33f2474592fa..5e3edad37191 100644 --- a/packages/shared_preferences/shared_preferences/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ b/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java @@ -27,7 +27,7 @@ * responsible of managing the {@link android.content.SharedPreferences}. */ @SuppressWarnings("unchecked") -class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { +public class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { private static final String SHARED_PREFERENCES_NAME = "FlutterSharedPreferences"; @@ -42,7 +42,7 @@ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { * Constructs a {@link MethodCallHandlerImpl} instance. Creates a {@link * android.content.SharedPreferences} based on the {@code context}. */ - MethodCallHandlerImpl(Context context) { + public MethodCallHandlerImpl(Context context) { preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); } From 34d0a70e7c2a84f0506ee514d69ec1041b05f801 Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 17:08:14 -0600 Subject: [PATCH 09/11] Replaced MethodCallHandlerImpl The class MethodCallHandlerImpl has been replaced with a kotlin version, also it has been added a validation to check persistence from android side. --- .../MethodCallHandlerImpl.java | 203 ------------------ .../MethodCallHandlerImpl.kt | 200 +++++++++++++++++ 2 files changed, 200 insertions(+), 203 deletions(-) delete mode 100644 packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java create mode 100644 packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.kt diff --git a/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java b/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java deleted file mode 100644 index 5e3edad37191..000000000000 --- a/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.sharedpreferences; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.AsyncTask; -import android.util.Base64; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Implementation of the {@link MethodChannel.MethodCallHandler} for the plugin. It is also - * responsible of managing the {@link android.content.SharedPreferences}. - */ -@SuppressWarnings("unchecked") -public class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { - - private static final String SHARED_PREFERENCES_NAME = "FlutterSharedPreferences"; - - // Fun fact: The following is a base64 encoding of the string "This is the prefix for a list." - private static final String LIST_IDENTIFIER = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu"; - private static final String BIG_INTEGER_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBCaWdJbnRlZ2Vy"; - private static final String DOUBLE_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBEb3VibGUu"; - - private final android.content.SharedPreferences preferences; - - /** - * Constructs a {@link MethodCallHandlerImpl} instance. Creates a {@link - * android.content.SharedPreferences} based on the {@code context}. - */ - public MethodCallHandlerImpl(Context context) { - preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - } - - @Override - public void onMethodCall(MethodCall call, MethodChannel.Result result) { - String key = call.argument("key"); - try { - switch (call.method) { - case "setBool": - commitAsync(preferences.edit().putBoolean(key, (boolean) call.argument("value")), result); - break; - case "setDouble": - double doubleValue = ((Number) call.argument("value")).doubleValue(); - String doubleValueStr = Double.toString(doubleValue); - commitAsync(preferences.edit().putString(key, DOUBLE_PREFIX + doubleValueStr), result); - break; - case "setInt": - Number number = call.argument("value"); - if (number instanceof BigInteger) { - BigInteger integerValue = (BigInteger) number; - commitAsync( - preferences - .edit() - .putString( - key, BIG_INTEGER_PREFIX + integerValue.toString(Character.MAX_RADIX)), - result); - } else { - commitAsync(preferences.edit().putLong(key, number.longValue()), result); - } - break; - case "setString": - String value = (String) call.argument("value"); - if (value.startsWith(LIST_IDENTIFIER) || value.startsWith(BIG_INTEGER_PREFIX)) { - result.error( - "StorageError", - "This string cannot be stored as it clashes with special identifier prefixes.", - null); - return; - } - commitAsync(preferences.edit().putString(key, value), result); - break; - case "setStringList": - List list = call.argument("value"); - commitAsync( - preferences.edit().putString(key, LIST_IDENTIFIER + encodeList(list)), result); - break; - case "commit": - // We've been committing the whole time. - result.success(true); - break; - case "getAll": - result.success(getAllPrefs()); - return; - case "remove": - commitAsync(preferences.edit().remove(key), result); - break; - case "clear": - Set keySet = getAllPrefs().keySet(); - SharedPreferences.Editor clearEditor = preferences.edit(); - for (String keyToDelete : keySet) { - clearEditor.remove(keyToDelete); - } - commitAsync(clearEditor, result); - break; - default: - result.notImplemented(); - break; - } - } catch (IOException e) { - result.error("IOException encountered", call.method, e); - } - } - - private void commitAsync( - final SharedPreferences.Editor editor, final MethodChannel.Result result) { - new AsyncTask() { - @Override - protected Boolean doInBackground(Void... voids) { - return editor.commit(); - } - - @Override - protected void onPostExecute(Boolean value) { - result.success(value); - } - }.execute(); - } - - private List decodeList(String encodedList) throws IOException { - ObjectInputStream stream = null; - try { - stream = new ObjectInputStream(new ByteArrayInputStream(Base64.decode(encodedList, 0))); - return (List) stream.readObject(); - } catch (ClassNotFoundException e) { - throw new IOException(e); - } finally { - if (stream != null) { - stream.close(); - } - } - } - - private String encodeList(List list) throws IOException { - ObjectOutputStream stream = null; - try { - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - stream = new ObjectOutputStream(byteStream); - stream.writeObject(list); - stream.flush(); - return Base64.encodeToString(byteStream.toByteArray(), 0); - } finally { - if (stream != null) { - stream.close(); - } - } - } - - // Filter preferences to only those set by the flutter app. - private Map getAllPrefs() throws IOException { - Map allPrefs = preferences.getAll(); - Map filteredPrefs = new HashMap<>(); - for (String key : allPrefs.keySet()) { - if (key.startsWith("flutter.")) { - Object value = allPrefs.get(key); - if (value instanceof String) { - String stringValue = (String) value; - if (stringValue.startsWith(LIST_IDENTIFIER)) { - value = decodeList(stringValue.substring(LIST_IDENTIFIER.length())); - } else if (stringValue.startsWith(BIG_INTEGER_PREFIX)) { - String encoded = stringValue.substring(BIG_INTEGER_PREFIX.length()); - value = new BigInteger(encoded, Character.MAX_RADIX); - } else if (stringValue.startsWith(DOUBLE_PREFIX)) { - String doubleStr = stringValue.substring(DOUBLE_PREFIX.length()); - value = Double.valueOf(doubleStr); - } - } else if (value instanceof Set) { - // This only happens for previous usage of setStringSet. The app expects a list. - List listValue = new ArrayList<>((Set) value); - // Let's migrate the value too while we are at it. - boolean success = - preferences - .edit() - .remove(key) - .putString(key, LIST_IDENTIFIER + encodeList(listValue)) - .commit(); - if (!success) { - // If we are unable to migrate the existing preferences, it means we potentially lost them. - // In this case, an error from getAllPrefs() is appropriate since it will alert the app during plugin initialization. - throw new IOException("Could not migrate set to list"); - } - value = listValue; - } - filteredPrefs.put(key, value); - } - } - return filteredPrefs; - } -} diff --git a/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.kt b/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.kt new file mode 100644 index 000000000000..608e7d62ee1a --- /dev/null +++ b/packages/shared_preferences/shared_preferences/android/src/main/kotlin/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.kt @@ -0,0 +1,200 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +package io.flutter.plugins.sharedpreferences +import android.content.Context +import android.content.SharedPreferences +import android.os.AsyncTask +import android.util.Base64 +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.io.ObjectInputStream +import java.io.ObjectOutputStream +import java.math.BigInteger +import java.util.ArrayList +import java.util.HashMap +/** +* Implementation of the {@link MethodChannel.MethodCallHandler} for the plugin. It is also +* responsible of managing the {@link android.content.SharedPreferences}. +*/ +class MethodCallHandlerImpl/** + * Constructs a {@link MethodCallHandlerImpl} instance. Creates a {@link + * android.content.SharedPreferences} based on the {@code context}. + */ +(context:Context):MethodChannel.MethodCallHandler { + private val preferences:android.content.SharedPreferences + private var editor: SharedPreferences.Editor? = null + // Filter preferences to only those set by the flutter app. + private// This only happens for previous usage of setStringSet. The app expects a list. + // Let's migrate the value too while we are at it. + // If we are unable to migrate the existing preferences, it means we potentially lost them. + // In this case, an error from getAllPrefs() is appropriate since it will alert the app during plugin initialization. + val allPrefs:Map + + @Throws(IOException::class) + get() { + val allPrefs = preferences.all + val filteredPrefs = HashMap() + for (key in allPrefs.keys) { + if (key.startsWith("flutter.")) { + var value = allPrefs[key] + if (value is String) { + val stringValue = value + when { + stringValue.startsWith(LIST_IDENTIFIER) -> { + value = decodeList(stringValue.substring(LIST_IDENTIFIER.length)) + } + stringValue.startsWith(BIG_INTEGER_PREFIX) -> { + val encoded = stringValue.substring(BIG_INTEGER_PREFIX.length) + value = BigInteger(encoded, Character.MAX_RADIX) + } + stringValue.startsWith(DOUBLE_PREFIX) -> { + val doubleStr = stringValue.substring(DOUBLE_PREFIX.length) + value = java.lang.Double.valueOf(doubleStr) + } + } + } + else if (value is Set<*>) { + val listValue = value.map { it.toString() }.toMutableList() + val success = preferences + .edit() + .remove(key) + .putString(key, LIST_IDENTIFIER + encodeList(listValue)) + .commit() + if (!success) { + throw IOException("Could not migrate set to list") + } + value = listValue + } + value?.let { filteredPrefs.put(key, it) } + } + } + return filteredPrefs + } + + init { + preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE) + } + + override fun onMethodCall(call:MethodCall, result:MethodChannel.Result) { + val key = call.argument("key") as String? + try + { + when (call.method) { + "setBool" -> commitAsync(preferences.edit().putBoolean(key, call.argument("value") as Boolean), result) + "setDouble" -> { + val doubleValue = (call.argument("value") as Number).toDouble() + val doubleValueStr = doubleValue.toString() + commitAsync(preferences.edit().putString(key, DOUBLE_PREFIX + doubleValueStr), result) + } + "setInt" -> { + val number = call.argument("value") + if (number is BigInteger) + { + val integerValue = number as BigInteger + commitAsync( + preferences + .edit() + .putString( + key, BIG_INTEGER_PREFIX + integerValue.toString(Character.MAX_RADIX)), + result) + } + else + { + commitAsync(preferences.edit().putLong(key, number!!.toLong()), result) + } + } + "setString" -> { + val value = call.argument("value") as String + if (value.startsWith(LIST_IDENTIFIER) || value.startsWith(BIG_INTEGER_PREFIX)) + { + result.error( + "StorageError", + "This string cannot be stored as it clashes with special identifier prefixes.", null) + return + } + commitAsync(preferences.edit().putString(key, value), result) + } + "setStringList" -> { + val list = call.argument>("value") as List + commitAsync( + preferences.edit().putString(key, LIST_IDENTIFIER + encodeList(list)), result) + } + "commit" -> + // We've been committing the whole time. + result.success(true) + "getAll" -> { + result.success(allPrefs) + return + } + "remove" -> commitAsync(preferences.edit().remove(key), result) + "clear" -> { + val keySet = allPrefs.keys + val clearEditor = preferences.edit() + for (keyToDelete in keySet) + { + clearEditor.remove(keyToDelete) + } + commitAsync(clearEditor, result) + } + else -> result.notImplemented() + } + } + catch (e:IOException) { + result.error("IOException encountered", call.method, e) + } + } + + private fun commitAsync( + editor:SharedPreferences.Editor, result:MethodChannel.Result) { + object:AsyncTask() { + override protected fun doInBackground(vararg voids:Void):Boolean { + return editor.commit() + } + override protected fun onPostExecute(value:Boolean) { + result.success(value) + } + }.execute() + } + + @Throws(IOException::class) + private fun decodeList(encodedList:String):List { + var stream:ObjectInputStream? = null + try { + stream = ObjectInputStream(ByteArrayInputStream(Base64.decode(encodedList, 0))) + return stream.readObject() as List + } + catch (e:ClassNotFoundException) { + throw IOException(e) + } + finally { + stream?.let { it.close() } + } + } + + @Throws(IOException::class) + private fun encodeList(list:List):String { + var stream:ObjectOutputStream? = null + try { + val byteStream = ByteArrayOutputStream() + stream = ObjectOutputStream(byteStream) + stream.writeObject(list) + stream.flush() + return Base64.encodeToString(byteStream.toByteArray(), 0) + } + finally { + stream?.let { it.close() } + } + } + + companion object { + private val SHARED_PREFERENCES_NAME = "FlutterSharedPreferences" + // Fun fact: The following is a base64 encoding of the string "This is the prefix for a list." + private val LIST_IDENTIFIER = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu" + private val BIG_INTEGER_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBCaWdJbnRlZ2Vy" + private val DOUBLE_PREFIX = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBEb3VibGUu" + } +} \ No newline at end of file From 266448007fb27287c7646eb347bdb25fcc8aa3cd Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 17:13:01 -0600 Subject: [PATCH 10/11] Updated changelog.md --- packages/shared_preferences/shared_preferences/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 139df388ec73..c237ea07f490 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.13 + +* Migrated preferences functionality to utilize kotlin. + ## 0.5.12 * Keep handling deprecated Android v1 classes for backward compatibility. From eab4ada2000d3847d4f3736f73ac05b4a7e5b3c5 Mon Sep 17 00:00:00 2001 From: Luis Cardoza Bird Date: Sun, 11 Oct 2020 17:21:26 -0600 Subject: [PATCH 11/11] Updated version in pubspec.yaml --- packages/shared_preferences/shared_preferences/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index aebd0a038671..7c954e00439b 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/shared_prefere # 0.5.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.5.12 +version: 0.5.13 flutter: plugin: