preface

I recently developed a Flutter plugin for Android app version update in my spare time: Flutter_xupdate. I didn’t encounter any bugs in the process of development, but I did encounter a lot of problems when publishing to the Flutter plugin platform. Here IS a note to give some advice to others.

Development of the Flutter Plugin

1. Create the Flutter Plugin project

It is recommended to create a project using Android Studio. Follow the instructions step by step.The generated project directory mainly contains the following:

  • The “Android” directory is the implementation of the plug-in API on the Android platform.
  • The “ios” directory is the implementation of the plug-in API on the ios platform.
  • The “Example” directory is an example project that uses plug-ins.
  • Files in the “lib” directory, which basically creates a “MethodChannel” and then receives and processes messages from the native platform

2. Implement plug-in functions

Here I mainly introduce the implementation of API on Android.

Trap 1: There are two versions of the Flutter plugin loading

The Registrar and FlutterPluginBinding versions of Flutter automatically depend on the plugin, so it would be best to implement both at the Android plugin level to improve compatibility. Therefore,Android plug-ins need to implement FlutterPlugin, ActivityAware, MethodCallHandler these three interfaces, taking my Flutter_xUpdate plug-in as an example, the implementation is as follows:

public class FlutterXUpdatePlugin implements FlutterPlugin, ActivityAware, MethodCallHandler { private static final String PLUGIN_NAME = "com.xuexiang/flutter_xupdate"; private MethodChannel mMethodChannel; private Application mApplication; private WeakReference<Activity> mActivity; @override public void onAttachedToEngine(@nonnull FlutterPluginBinding FlutterPluginBinding) { mMethodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), PLUGIN_NAME); mApplication = (Application) flutterPluginBinding.getApplicationContext(); mMethodChannel.setMethodCallHandler(this); } @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { mMethodChannel.setMethodCallHandler(null); mMethodChannel = null; } public FlutterXUpdatePlugin initPlugin(MethodChannel methodChannel, Registrar registrar) { mMethodChannel = methodChannel; mApplication = (Application) registrar.context().getApplicationContext(); mActivity = new WeakReference<>(registrar.activity()); return this; } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { switch (call.method) { case "getPlatformVersion": result.success("Android " + android.os.Build.VERSION.RELEASE); break; case "initXUpdate": initXUpdate(call, result); break; . default: result.notImplemented(); break; } } @Override public void onAttachedToActivity(ActivityPluginBinding binding) { mActivity = new WeakReference<>(binding.getActivity()); } @Override public void onDetachedFromActivityForConfigChanges() { } @Override public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) { } @Override public void onDetachedFromActivity()  { mActivity = null; Public static void registerWith(Registrar) {final MethodChannel channel = new MethodChannel(registrar.messenger(), PLUGIN_NAME); channel.setMethodCallHandler(new FlutterXUpdatePlugin().initPlugin(channel, registrar)); }}Copy the code

The above code needs to be noted:

  • registerWithThe static method of flutter is the old way of loading the plugin, by reflection.
  • onAttachedToEngineandonDetachedFromEngineisFlutterPluginThe interface method for Flutter is the new way to load plug-ins.
  • onAttachedToActivityandonDetachedFromActivityisActivityAwareGets the Activity of the current flutter page.
  • onMethodCallisMethodCallHandlerIs used to receive implementations of native method calls on the Flutter side.

Pit 2: There are limitations on the type of data interaction between native and FLUTTER

Data interaction between native and FLUTTER must be involved in the development of the plugin. One thing to note here is that not all types of data support interaction, as we did with React native and JNI. Here I give the data types that native and FLUTTER can interact with:

Dart Android iOS
null null nil (NSNull when nested)
bool java.lang.Boolean NSNumber numberWithBool:
int java.lang.Integer NSNumber numberWithInt:
int, if 32 bits not enough java.lang.Long NSNumber numberWithLong:
double java.lang.Double NSNumber numberWithDouble:
String java.lang.String NSString
Uint8List byte[] FlutterStandardTypedData typedDataWithBytes:
Int32List int[] FlutterStandardTypedData typedDataWithInt32:
Int64List long[] FlutterStandardTypedData typedDataWithInt64:
Float64List double[] FlutterStandardTypedData typedDataWithFloat64:
List java.util.ArrayList NSArray
Map java.util.HashMap NSDictionary

The types we use most here are bool, int, String, Map

3. Plug-in release

Plug-in publishing encounters the most potholes and requires extra attention.

Perfect the documents

It is recommended that you add the following documents to your plug-in project:

  • README.md: Describes the package file
  • CHANGELOG.md Record the changes in each release
  • LICENSEA file containing the package license terms
  • API documentation for all public apis

Release the plugin

Run the following command to publish:

flutter packages pub publish
Copy the code

You think this is it? No, no, no, there are so many holes down there!!

Pit 3: Permission authentication requires access to a Google account

Since we want to publish the plugin to the Flutter platform, which is built by Google, to publish the plugin, we need to log into our Google account for authentication. After entering the flutter Packages pub publish command, we will receive an authentication link that requires us to log into our Google account.

To know that Google is not accessible in China, here we need to find a way (you know what method) to log in Google account and authenticate.

Pit # 4: Documents created by Flutter Chinese are toxic

You think you’re done signing into your Google account? Too much thinking! There is a problem with the environment configuration of Flutter, as shown below:Here we are officially asked to configure the temporary image of Flutter. Generally, when you first get to Flutter, you must follow the official document step by step. Can be such an insignificant step, let me in the certification step has been stuck. Searching the Internet for a solution didn’t work. Some people say that it is because of the configuration of the mirror problem, I dare not how also do not believe that is caused by this problem.

Here we remove the mirror configuration can pass authentication.

Pit # 5: Scientific Web tools don’t work on command terminals

I thought I could upload successfully once I was successfully authenticated, but unexpectedly I was stuck on the Uploading for a long time… In any case, the upload failed.

Uploading...
Failed to upload the package.
Copy the code

Baidu on the Internet, it is said that the scientific Internet tools do not work on the command terminal, the need to set up the command line agent.

Export https_proxy=http://127.0.0.1:1087 export http_proxy=http://127.0.0.1:1087 set https_proxy=https://127.0.0.1:1087 The set http_proxy = http://127.0.0.1:1087Copy the code

Because I’m using the science web tool Jet MAC, my proxy port is 1087.

But the direct setting is also unable to upload successful. We need to use the privoxy tool to complete the terminal agent, the operation is as follows:

  • Install privoxy
brew install privoxy
Copy the code
  • Modify the Privoxy configuration
vim /usr/local/etc/privoxy/config
Copy the code

Add these two configurations (note that the port number in the first line depends on your sciencenet agent, I haven’t changed it; it defaults to 1087), and don’t forget to include a space and a dot at the end.

Listen-address 0.0.0.0:1087 forward-socks5 / localhost:1080.Copy the code
  • Start the privoxy
sudo /usr/local/sbin/privoxy /usr/local/etc/privoxy/config
Copy the code

After starting, let’s check to see if it is started:

netstat -na | grep 1087
Copy the code

If information similar to the following is displayed, the startup is successful.

Tcp4 0 0 127.0.0.1.1087 *.* LISTENCopy the code

At this point, execute again:

Export https_proxy=http://127.0.0.1:1087 export http_proxy=http://127.0.0.1:1087 set https_proxy=https://127.0.0.1:1087 The set http_proxy = http://127.0.0.1:1087Copy the code

Finally, execute the publish command:

flutter packages pub publish
Copy the code

If the following results appear, the release is successful!

Waiting for your authorization...

Authorization received, processing...

Successfully authorized.

Uploading...

Successfully uploaded package.

Copy the code

A link to the

  • Learn how to create a Plugin for Flutter
  • Flutter_xupdate One-click implementation of Flutter application version update

Wechat official account

More information, welcome wechat search public number: “My Android open source journey”