Android native plug-in development for uni-app

A plug-in introduction

1.1 When the capabilities provided in HBuilderX cannot meet the functional requirements of the App, and it needs to be realized by using Andorid/iOS native development, you can use the App offline SDK to develop native plug-ins to expand the native capabilities.

1.2 There are two types of plug-ins, Module mode and Component mode

  • Module mode: Capability expansion, no UI controls embedded in forms. Most plug-ins fall into this category, such as calling the pedometer API. The code is written by requiring through js, and then calling the method of the plug-in object. If it involves some pop-up boxes and full-screen UI, it still belongs to Module mode. Similar to js sdk in the front end.
  • Component mode: Display a native UI component inline in the form. For example, if a map component of a map manufacturer is partially embedded in a form, and other front-end content is mixed up and down, it is necessary to encapsulate this native map sdk into a Component mode. The code writing method is the same as the vue component, and the component label is written in the template. Similar to the vue component in the front end.

1.3 Use of plug-ins: After the native plug-in is developed, it can be listed on the plug-in market or not. For internal use, there is no need to list the plug-in market. If you want to go to the plug-in market, you must compress it into a zip package in the specified format. 

The development of the second plug-in

2.1 The plug-in must be developed on the basis of uni-sdk. You can quickly download the offline uni-sdk, import the UniPlugin-Hello-AS sample project, or create a native android project yourself, and copy unnecessary packages and resources for development.

2.2 Offline uni-sdk download address:  https://nativesupport.dcloud.net.cn/AppDocs/download/android.html , which contains necessary resources and sample projects.

2.3 In the previous article, a new android project has been created and the uni resource project has been successfully packaged offline. Now we will develop plug-ins based on this.

2.4 Right-click on the androidStudio project to create a new plug-in Module

 2.5 Select library, fill in the module name, and click finish

2.6 Then depend on the module in the app’s build.gradle

implementation project(':mylibrary') 

2.6 Configure related dependent libraries in build.gradle in module

uniapp-v8-release.aar is the main dependent library of the extension module and must be imported.

compileOnly fileTree(include: ['uniapp-v8-release.aar'], dir: '../app/libs')

com.alibaba:fastjson is also necessary and depends on it. It will be used in json communication later.

implementation 'com.alibaba:fastjson:1.2.83'

At the same time, in order to avoid conflicts with the main app, all dependency types are changed to compileOnly, which means that only this module is valid.

dependencies {
    compileOnly 'androidx.appcompat:appcompat:1.5.0'
    compileOnly 'com.google.android.material:material:1.6.1'

    compileOnly 'com.alibaba:fastjson:1.2.83'
    compileOnly fileTree(include: ['uniapp-v8-release.aar'], dir: '../app/libs')
}

2.7 To create the TestModule class, you must inherit the UniModule class

  • Extension methods must be annotated with @UniJSMethod (uiThread = false or true). UniApp will use annotations to determine whether the current method is to be run on the UI thread and whether the current method is an extension method.
  • UniApp calls Module extension methods based on reflection, so the extension methods in Module must be of public type.

Example: Create two methods

public class TestModule extends UniModule {
    private static final String TAG = "TestModule";
    //run ui thread
    @UniJSMethod(uiThread = true)
    public void testAsyncFunc(JSONObject options, UniJSCallback callback) {
        Log.e(TAG, "testAsyncFunc--"+options);
        if(callback != null) {
            JSONObject data = new JSONObject();
            data.put("code", "success");
            callback.invoke(data);
        }
    }

    //run JS thread
    @UniJSMethod (uiThread = false)
    public JSONObject testSyncFunc(){
        JSONObject data = new JSONObject();
        data.put("code", "success");
        return data;
    }

}

2.8 Register the plug-in, create a new dcloud_uniplugins.json in the assets of androidStudio, and register the plug-in information

{
  "nativePlugins": [
    {
      "plugins": [
        {
          "type": "module",
          "name": "TestModule",
          "class": "com.juai.plugin_module.TestModule"
        }
      ]
    }
  ]
}

2.9 Callback event UniJSCallback: When called by JS, some scenarios need to return some data, such as the following example, which returns x and y coordinates.

  • invokeCall the javascript callback method, this method will be destroyed after being called.
  • invokeAndKeepAlive Call a javascript callback method and keep the callback active for later use.

The simple plug-in module above has been written. Now let’s do a simple test.

3.1 Write a button in the uni-app project page to call the plug-in. First add a button and set the click event.

<button type="primary" @click="testAsyncFunc">testAsyncFunc</button>

3.2 Get the newly written TestModule plug-in 

var testModule = uni.requireNativePlugin("TestModule")

 In 3.3 method, register the click event and call the native plug-in method

testAsyncFunc() {
	// 获取 module
	var testModule = uni.requireNativePlugin("TestModule")
	// 调用异步方法
	testModule.testAsyncFunc({
			'name': 'unimp',
			'age': 1
		},
		e => {
			uni.showToast({
				title: JSON.stringify(e),
				icon:'none'
			});
		}
	)
}

3.4 Complete vue example

<template>
	<view class="content">
		<image class="logo" src="/static/logo.png"></image>
		<view class="text-area">
			<text class="title">{
   
   {title}}</text>
		</view>
		
		<button type="primary" @click="testAsyncFunc">testAsyncFunc</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {

		},
		methods: {
            testAsyncFunc() {
				// 获取 module
				var testModule = uni.requireNativePlugin("TestModule")
				// 调用异步方法
				testModule.testAsyncFunc({
						'name': 'unimp',
						'age': 1
					},
					e => {
						uni.showToast({
					     	title: JSON.stringify(e),
							icon:'none'
						});
					}
				)
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

3.5 Packaging app resources

3.7 Replace the resource package in the androidStudio project

3.8 When you run the project, you will see that the button you just created is already there. Clicking on Android will get uni’s json data, indicating that the plug-in is called successfully.

3.9 At the same time, you can also see that there are logs in the androidStudio console, and the plug-in call is successful.

Four plug-in package

4.1 The above is only possible for android native offline debugging, so how to use this native plug-in in uni. First, generate the aar package of the plug-in. Find the Gradle tool in the androidStudio sidebar -> then find the project's Task directory -> other directory -> click assembleRelease and wait for the compilation to complete.

4.2 You can see that an aar is generated under the build of the plug-in module.

4.3 Create a nativeplugins folder in the root directory of the uni project -> create a plugin name directory TestModule -> create an android directory again, and copy the aar just now to the android directory

 4.4 Create a pakage.json under the plug-in directory to configure plug-in information

{
    "name": "TestModule",
    "id": "TestModule", // 插件标识
    "version": "1.0.0",
    "description": "插件描述信息",
    "_dp_type":"nativeplugin",
    "_dp_nativeplugin":{
        "android": {
			"integrateType":"aar",
            "plugins": [
                {
                    "type": "module",
                    "name": "TestModule", //id为前缀
                    "class": "com.juai.plugin_module.TestModule"
                }
                
            ]
        }
    }
}

4.5 This example is relatively simple. If you have an so library and a jar package, you also need to configure this information. The complete directory structure is as follows

 4.6 Identify local plugins in manifest.json

4.7 You can see that there is this plugin

4.8 Direct operation on the standard base is not possible, and the plug-in cannot be found. Need to test after cloud packaging

4.9 Select Release -> Cloud Packaging

Configure key information

4.10 Packaging error, saying that comments cannot be included in package.json, let’s remove them and try again

4.11 A new error occurred when re-packaging the cloud. It probably means that the minimum androidSDk version is too high, making the minimum 19

4.12 Then adjust minSDK to 19, regenerate aar, and replace the original aar.

Or add the conflicting configuration of the library in the plug-in module manifest file AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

   <uses-sdk tools:overrideLibrary="com.bun.miitmdid,com.juai.plugin_module" />

    ..............

</manifest>

4.13 You can see that the packaging is successful

4.14 Let’s run the apk on the mobile phone and see if it can run normally.

4.15 Note: There are times for cloud packaging. After ten or so times, cloud packaging will no longer be available today. Therefore, in order to save times, you can choose to customize the base operation or pack it with peace of mind.

Five-component Component development

5.1 Introduction to Component:

  • Component extends Native controls to implement special functions
  • Component does not support new Component creation of objects in code. Not working properly

5.2 androidStudio new component module 

5.3 Add necessary dependencies

compileOnly 'com.alibaba:fastjson:1.2.83'
compileOnly fileTree(include: ['uniapp-v8-release.aar'], dir: '../app/libs')

5.2 Create the TestComponent class. The Component extension class must inherit UniComponent, and the parent container Component (such as the ViewGroup component) needs to inherit UniVContainer.

public class TestText extends UniComponent<TextView>

5.3 UniComponent’s initComponentHostView callback function. This callback function is triggered when building the Component's view.

@Override
protected TextView initComponentHostView(@NonNull Context context) {
    TextView textView = new TextView(context);
    textView.setTextSize(20);
    textView.setTextColor(Color.BLACK);
    return textView;
}

5.4 The corresponding method of setting properties of Component must be annotated @UniComponentProp(name=value(value is attr or style of dsl))

@UniComponentProp(name = "tel")
public void setTel(String telNumber) {
    getHostView().setText("tel: " + telNumber);
}

5.5 Add this component dependency in the app’s build.gradle

implementation project(':ModuleComponent')

5.6 Register components in the dcloud_uniplugins.json file of the app’s assets

{
  "plugins": [
	{
	  "type": "component",
	  "name": "myText",
	  "class": "com.juai.modulecomponent.TestText"
	}
  ]
}

5.7 Add TestText component in uni project

<template>
    <myText ref="telText" tel="12305" style="width:200;height:100" @onTel="onTel" @click="myTextClick"></myText>
</template>

5.8 Add click events in the methods of the uni project

methods: {		
	myTextClick(e) {
		this.$refs.telText.clearTel();
	}
}

5.9 Complete uni example

<template>
	<div>
		<myText ref="telText" tel="12305" style="width:200;height:100" @onTel="onTel" @click="myTextClick"></myText>
	</div>
</template>
<script>  
    export default {  
        methods: {  
			myTextClick(e) {
				this.$refs.telText.clearTel();
			}
        }  
    } 
</script>  

5.10 uni packaged app resources

5.11 Copy the resource package to the assets of the androidStudio project

5.12 The component appears successfully when running. Package aar as well, copy it to the nativeplugins directory in the uni project, and configure pakage.json

5.13 After cloud packaging, it can be installed and run on the real machine 

6. Publish the plug-in to the DCloud market

6.1 As mentioned above, how to use local plug-ins, we can also publish the plug-in to the market, so that the plug-in can be used through remote dependencies. Publish plug-in address: https://ext.dcloud.net.cn/publish

6.2 Fill in basic information such as name

6.3 Pack the plug-in and generate a zip compressed package

6.4 Upload plug-in instructions md text

 

6.5 When publishing a plug-in, you may be prompted that the plug-in content is not included because the plug-in ID filled in above is inconsistent with the plug-in ID of the compressed package. We changed to unanimous

 

6.6 Because publishing plug-ins must be in this format, we will modify the plug-in ID name in the uni project

6.7 Re-publish, you can see that the release is successful

Guess you like

Origin blog.csdn.net/qq_29848853/article/details/132650734