談?wù)刢ordova 創(chuàng)建plugin

官方
插件開(kāi)發(fā)指南
Plugin.xml
因本人比較熟悉iOS , 所以創(chuàng)建的plugin 以iOS 為主, android 簡(jiǎn)單的涉及.
我們知道cordova plugin 是原生與html溝通的橋梁, cordova 可以說(shuō)是一個(gè)webView,加載一個(gè)大的html 頁(yè)面.相關(guān)的版面以html 網(wǎng)頁(yè)的形式出現(xiàn),而cordova plugin ,就好像你要打開(kāi)手機(jī)的相機(jī)功能,單靠html是完成不了這個(gè)功能的.所以就需要cordova plugin的存在, 它異常的重要.

目標(biāo)

這樣添加plugin

希望我們最后這樣使用就可以添加到cordova-plugin: (因未在registry.cordova.io中注冊(cè).暫指定備用URL)

cordova plugin add https://github.com/apache/cordova-plugin-console.git
cordova plugin add https://github.com/apache/cordova-plugin-console.git#r0.2.0
  • 如果插件(及其plugin.xml文件)位于git repo中的子目錄中,則可以使用:字符指定它。請(qǐng)注意,#仍然需要該 角色:
cordova plugin add https://github.com/someone/aplugin.git#:/my/sub/dir
  • 還可以將git-ref和子目錄結(jié)合使用:
cordova plugin add https://github.com/someone/aplugin.git#r0.0.1:/my/sub/dir
  • 或者,指定包含該plugin.xml文件的插件目錄的本地路徑:
cordova plugin add ../my_plugin_dir
刪除plugin
cordova plugin rm pluginName(可以打開(kāi)本地plugin list 看, 也可以執(zhí)行 cordova plugin list 看)

開(kāi)始創(chuàng)建我們的Plugin

  • 插件文件夾必須具有plugin.xml清單文件,所以我們可以簡(jiǎn)單地創(chuàng)建一個(gè)plugin.xml文件, 然后我們開(kāi)始對(duì)里面的參數(shù)做一一講解


    plugin.xml

    用工具打開(kāi)plugin.xml.

<?xml version="1.0" encoding="UTF-8"?>

<!-- xmlns: Required , 插件名稱空間,http://apache.org/cordova/ns/plugins/1.0。 如果文檔包含來(lái)自其他命名空間的XML,例如在Android的情況下要添加到AndroidManifest.xml文件的標(biāo)記,那么這些命名空間也應(yīng)該包含在元素中。-->
<!-- id, Required ,通常是this-is-a-plugin的形式,就像cordova-plugin-device(作為示例) -->
<!-- version,Required, 插件的版本號(hào) -->
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" 
  xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-netspay" version="0.1.0">
  <!-- name,用于指定插件的名稱。(尚未)處理本地化。-->
  <name>netspay</name>
  <!--description用于指定插件的描述.(尚未)處理本地化。-->
  <description>Cordova Plugin netspay</description>
  <!--author包含插件作者的名稱。-->
  <author>peijue chen</author>
  <!--關(guān)鍵字元素的內(nèi)容,可以用逗號(hào)分隔的-->
  <keywords>cordova, plugin, enets, netspay</keywords>
  <!--此元素用于指定插件的許可證。-->
  <license>MIT</license>
  <!---如果有pod , 請(qǐng)?zhí)砑哟? 
    如果不添加這個(gè),請(qǐng)先安裝: cordova plugin add cordova-plugin-cocoapod-support --save
  --->
  <dependency id="cordova-plugin-cocoapod-support"/>
  <!-- 指定的cordova 版本, 如果安裝時(shí)比它小, cordova 會(huì)終止.如果不指定,cordova 會(huì)不管三七二十一安裝.-->
  <!-- name : cordova/cordova-ios/cordova-android....-->
  <!-- <engines>
  <engine name="cordova" version=">=4.0.0" />
  <engine name="cordova-android" version=">=4.0.0" />
  <engine name="cordova-ios" version=">=1.7.1" />
  </engines> -->

  <!--  Custom frameworks example:-->
  <!--
  <engines>
  <engine name="my_custom_framework" version="1.0.0" platform="android" scriptSrc="path_to_my_custom_framework_version"/>
  <engine name="another_framework" version=">0.2.0" platform="ios|android" scriptSrc="path_to_another_framework_version"/>
  <engine name="even_more_framework" version=">=2.2.0" platform="*" scriptSrc="path_to_even_more_framework_version"/>
  </engines>
  -->

  <!-- js-module 
       src:插件目錄中相對(duì)于plugin.xml文件;  
       name 提供模塊名稱的最后一部分.可以是你喜歡的任何東西,如果你想在你的JavaScript代碼中使用cordova.require導(dǎo)入插件, 這里可以這樣輸入: var netspay = require('./netspay')
  <js-module>的模塊名稱是插件的id,后跟name的值。 -->
  <!-- clobbers: 用于指定插入module.exports的window對(duì)象下的命名空間。 您可以擁有任意數(shù)量的<clobbers>。 -->
  <!-- e.g: window.cordova.plugins.netspay  這里可以這樣使用-->
  <js-module src="www/netspay.js" name="netspay">
    <clobbers target="cordova.plugins.netspay" />
  </js-module>

  <!--  加入多個(gè), 也可以在某個(gè)平臺(tái)單獨(dú)指定
  <js-module src="www/PositionError.js" name="PositionError">
            <clobbers target="PositionError" />
        </js-module>
-->

  <!--<dependency>標(biāo)簽允許您指定當(dāng)前插件所依賴的其他插件。 插件由其唯一的 npm id或github url 引用。-->
  <!--
  <dependency id="cordova-plugin-someplugin" url="https://github.com/myuser/someplugin" commit="428931ada3891801" subdir="some/path/here" />
  <dependency id="cordova-plugin-someplugin" version="1.0.1">
  -->

  <!--如果不指定platform,就當(dāng)作只是JavaScript,可以安裝到任何平臺(tái)-->
  <!--Required ,Allowed values: ios, android, windows, browser, osx -->
  <!-- android -->
  <platform name="android">
    <config-file parent="/*" target="res/xml/config.xml">
      <feature name="NetsPay">
        <param name="android-package" value="cordova-plugin-netspay.NetsPay" />
      </feature>
    </config-file>

    <config-file target="AndroidManifest.xml" parent="/*">
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.READ_PHONE_STATE" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="normal" />
      <uses-permission android:name="com.nets.netspay.QR_TRANSACTION" />
    </config-file>

    <source-file src="src/android/NetsPay.java" target-dir="src/cordova-plugin-netspay/NetsPay" />

    <framework src="src/android/netspay.gradle" custom="true" type="gradleReference"/>
    <resource-file src="src/android/enetslib_UAT_1.2.1.aar" target="libs/enetslib_UAT_1.2.1.aar"/>
  <!--
  <resource-file src="FooPluginStrings.xml" target="res/values/FooPluginStrings.xml" />
// 添加配置
<config-file target="AndroidManifest.xml" parent="/manifest/application">
    <activity android:name="com.foo.Foo" android:label="@string/app_name">
        <intent-filter>
        </intent-filter>
    </activity>
</config-file>
-->

<!---
 On Android (as of cordova-android@4.0.0), framework tags are used to include Maven dependencies, or to include bundled library projects.
-->
<!-- Depend on latest version of GCM from play services
<framework src="com.google.android.gms:play-services-gcm:+" />
 -->
<!-- Depend on v21 of appcompat-v7 support library 
<framework src="com.android.support:appcompat-v7:21+" />
-->
<!-- Depend on library project included in plugin 
<framework src="relative/path/FeedbackLib" custom="true" />
-->

<!--
Framework can also be used to have custom .gradle files sub-included into the main project's build.gradle file:

<framework src="relative/path/rules.gradle" custom="true" type="gradleReference" />

On Windows, using custom='true' and type='projectReference' will add a reference to the project which will be added to the compile+link steps of the cordova project. This essentially is the only way currently that a 'custom' framework can target multiple architectures as they are explicitly built as a dependency by the referencing cordova application.

<framework src="path/to/project/LibProj.csproj" custom="true" type="projectReference"/>

Examples of using these Windows specific attributes:
<framework src="src/windows/example.dll" arch="x64" />
<framework src="src/windows/example.dll" versions=">=8.0" />
<framework src="src/windows/example.vcxproj" type="projectReference" target="win" />
<framework src="src/windows/example.vcxproj" type="projectReference" target="all" versions="8.1" arch="x86" />
<framework src="src/windows/example.dll" target-dir="bin/x64" arch="x64" custom="true"/>
-->
<!--
Another example of using Windows-specific attributes to add a reference to WinMD components, written in C# and C++, whose API will be available at runtime:
-->
<!-- C# component that consists of one .winmd file 
<framework src="lib\windows\component.winmd" versions="<10.0" />
-->

<!-- C++ component with separated metadata and implementation
<framework src="lib\windows\x86\cppcomponent.winmd"
           implementation="lib\windows\x86\cppcomponent.dll"
           target-dir="component\x86" arch="x86" versions=">=10.0" />
-->
  </platform>

  <!-- ios -->
  <platform name="ios">

    <!--
      這個(gè)配置相當(dāng)重要, feature 中的name 你可以寫 上面的id ,
      param 的name 寫: ios-package ,  但value : 一定要寫你本地的.m /.swift 文件的 class 名字, cordova 要用它來(lái)call 方法.
    -->
    <config-file target="config.xml" parent="/*">
      <feature name="NetsPay">
        <param name="ios-package" value="NetsPay" />
      </feature>
    </config-file>

      <!-- 配置info 文件 -->
      <!---往info.plist 中添加?xùn)|西, 可以設(shè)置默認(rèn)值, 在外面添加plugin 時(shí)也可以根據(jù)GEOLOCATION_USAGE_DESCRIPTION來(lái)添加, 請(qǐng)往下看-->
     <preference name="GEOLOCATION_USAGE_DESCRIPTION" default="Enable access for location helps us to show you nearest stores." />
     <config-file target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription">
        <string>$GEOLOCATION_USAGE_DESCRIPTION</string>
      </config-file> 

    <!-- add url schemes -->
    <config-file target="*-Info.plist" parent="CFBundleURLTypes">
      <array>
        <dict>
          <key>CFBundleURLName</key>
          <string>bundle.id</string>
          <key>CFBundleURLSchemes</key>
          <array>
            <string>netspaySchemes</string>
          </array>
        </dict>
      </array>
    </config-file>

    <!-- 頭文件, 只復(fù)制文件進(jìn)cordova項(xiàng)目, 不參與編譯 -->
    <header-file src="src/ios/NetsPay.h" />
    <!--安裝到項(xiàng)目中的可執(zhí)行源代碼。-->
    <source-file src="src/ios/NetsPay.m" />
    <!--<source-file src="src/ios/Netspay.swift" />-->
    
    <!--compiler-flags: 如果設(shè)置,則為特定源文件指定指定的編譯器標(biāo)志。-->
    <!--
    <source-file src="src/ios/someLib.a" compiler-flags="-fno-objc-arc" />
-->

    <!-- 系統(tǒng)庫(kù) -->
    <!-- alipay depen -->
    <!-- <framework src="libc++.tbd" />
    <framework src="libz.tbd" />
    <framework src="SystemConfiguration.framework" />
    <framework src="CoreTelephony.framework" />
    <framework src="QuartzCore.framework" />
    <framework src="CoreText.framework" />
    <framework src="CoreGraphics.framework" />
    <framework src="UIKit.framework" />
    <framework src="Foundation.framework" />
    <framework src="CFNetwork.framework" />
    <framework src="CoreMotion.framework" /> -->

    <!-- pod framework 但僅限靜態(tài)庫(kù), 必須: cordova-ios@4.3.0 and cordova-cli 6.4.0
          如果使用該屬性, 請(qǐng)?jiān)O(shè)置好 cordova-ios 版本. 
    -->
    <!---或者這種情況-->
    <pods-config ios-min-version="8.0" use-frameworks="true"/>    
    <pod id="GoogleConversionTracking" version="3.4.0"/>
    <pod id="FirebaseAppIndexing" version="1.0.3"/>
    <!-- <framework src="OrderPlaceSdk" type="podspec" spec="~> 0.1.3" /> -->
     
    <!--包含本地需要說(shuō)明的文件或頭文件-->
    <!-- <header-file src="src/ios/WechtSDK1.8.2/WechatAuthSDK.h" />
    <header-file src="src/ios/WechtSDK1.8.2/WXApi.h" />
    <header-file src="src/ios/WechtSDK1.8.2/WXApiObject.h" />
    <header-file src="src/ios/WechtSDK1.8.2/README.txt" />

    //  如果設(shè)置為true,則還將指定的文件作為框架添加到項(xiàng)目中。
    <source-file src="src/ios/WechtSDK1.8.2/libWeChatSDK.a" framework="true" />
    // 這類似于<source-file>元素,但專門針對(duì)iOS和Android等平臺(tái),用于區(qū)分源文件,頭文件和資源。
    //  寫入xcode 中:  copy bundle resource 中 一般為 xml bundle 文件
    <resource-file src="src/ios/AlipaySDK.bundle" /> -->

    <!--
      .a 靜態(tài)庫(kù), 請(qǐng)往上看, 需要用  source-file
      custom: 指示framework是否包含在插件文件中。也就是本地庫(kù), 如果是系統(tǒng)庫(kù)不需要 custom="true" 
      embed="true"需要配合custom="true"使用, 就是可以將你的動(dòng)態(tài)庫(kù)嵌入到應(yīng)用程序中, 但需要: cordova-ios@4.4.0 and cordova-cli@7.0.0 , 如果使用該屬性, 請(qǐng)?jiān)O(shè)置好 cordova-ios 版本. 
    <framework src="src/ios/OrderPlaceSDK.framework" custom="true" embed="true" /> 

    <framework src="src/ios/iOS_ENETS_SDK_UAT/Alamofire.framework" custom="true" />
    <framework src="src/ios/iOS_ENETS_SDK_UAT/Caishen.framework" custom="true" />
    <framework src="src/ios/iOS_ENETS_SDK_UAT/CryptoSwift.framework" custom="true" />
    <framework src="src/ios/iOS_ENETS_SDK_UAT/ENETSLib.framework" custom="true" />
    <framework src="src/ios/iOS_ENETS_SDK_UAT/MBProgressHUD.framework" custom="true" />
    <framework src="src/ios/iOS_ENETS_SDK_UAT/Presentr.framework" custom="true" />
    <framework src="src/ios/iOS_ENETS_SDK_UAT/SwiftyJSON.framework" custom="true" />
    -->
    
  </platform>

</plugin>

到此我們的plugin.xml 就配置好了, 這里需要添加的文件就放到對(duì)應(yīng)的文件夾下面就可以
目前我的結(jié)構(gòu)類似這樣


不單單這些
不單單這些
不單單這些
  • 其中 LICENSE ,是許可證, 可以用txt 文件寫一個(gè),不要后綴,名字是: LICENSE就可以.
  • package.json 可以說(shuō)是配置文件吧.
  • README.md , 可以寫上這個(gè)plugin 怎么用之類的, 如果上傳到gitHub , 它會(huì)插件的首頁(yè)顯示.
  • src: 是放ios/android 原生代碼的地方
  • www: 放的是js 文件
package.json
// version/ name/description, 與plugin.xml中保持一致
// repository, 是你放到gitHub 上的倉(cāng)庫(kù)
// bugs 是gitHub的issues 討論區(qū)
{
    "version": "0.1.0",
    "name": "cordova-plugin-netspay",
    "cordova_name": "cordova-plugin-netspay",
    "description": "cordova-plugin-netspay",
    "license": "Apache 2.0",
    "author": {
        "name": "Joson",
        "email": "xxxx@xxx.com"
    },
    "repository": {
        "type": "git",
        "url": "https://github.com/PeiJueChen/cordova-plugin-netspay.git"
    },
    "bugs": {
        "url": "https://github.com/PeiJueChen/cordova-plugin-netspay.git/issues"
    },
    "keywords": [
        "cordova",
        "plugin",
        "netspay"
    ]
}

js 文件怎么寫 , js 文件一般放在www 文件夾下, 這是規(guī)范

/**
 * 
 * exec(callback, errorCallback, pluginName, actionName, argumentArray)
 * callback 插件成功返回時(shí)調(diào)用,并將本機(jī)插件中的任何參數(shù)傳遞給它
 * errorCallback在插件遇到錯(cuò)誤時(shí)調(diào)用。我們?cè)谏厦媸÷粤诉@一點(diǎn)
 * pluginName 是本機(jī)端的插件類名稱。就是類名  (feature 下param 中的value , 它也要和原生代碼中的類名對(duì)上.)
 * actionName 是我們將在本機(jī)方面執(zhí)行的操作。
 * argumentArray 是傳遞給本機(jī)端的參數(shù)數(shù)組
 */

// prototype 屬於是為class 添加方法/屬於用到的
var exec = require('cordova/exec'),
    cordova = require('cordova'),
    // utils = require('cordova/utils'),

    // 如果需要引用本地js, 已經(jīng)在Plugin.xml 中
    // <js-module src="www/PositionError.js" name="PositionError">
    //    <clobbers target="PositionError" />
    //  </js-module>
    //PositionError = require('./PositionError');

var NetsPay = (function () {
    // var platformId = cordova.platformId;  // 'android' 'ios'
    function NetsPay() {
        // console.log("platformId: " + platformId + code);
    }
    // 建議加上cordova調(diào)用, 因?yàn)橹蟮陌姹綾ordova 提示說(shuō)需要加cordova在前面調(diào)用
    NetsPay.prototype.requestPay = function (echoValue, successCallback, errorCallback) {
        cordova.exec(successCallback, errorCallback, 'NetsPay', 'requestPay', [echoValue]);
    };

    return NetsPay;

})();

var netsPay = new NetsPay();
// 導(dǎo)出屬性, 調(diào)試時(shí), window. 就會(huì)有提示這個(gè)屬性.
module.exports = netsPay;

下面看看 NetsPay 文件

  • iOS
#import "NetsPay.h"
#import <Cordova/CDVPluginResult.h>
#import <ENETSLib/ENETSLib-Swift.h>
@interface NetsPay ()<PaymentRequestDelegate>
@property (strong, nonatomic) NSString* requestPayCallbackId;
@end

@implementation NetsPay

- (void)requestPay:(CDVInvokedUrlCommand*)command
{
    
    NSString* callbackId = [command callbackId];
    self.requestPayCallbackId = callbackId;
    
    // do something
    [self pay:command];

// 說(shuō)幾點(diǎn)注意的,  傳過(guò)來(lái)的參數(shù)可以根據(jù) [command.arguments objectAtIndex:0];  索引拿到
//  想調(diào)用回調(diào)時(shí): 
/*
CDVCommandStatus_OK , 這個(gè)值cordova 提供多種了,可以選擇
NSDictionaray *dict = @{@"key":@"value"};
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
                                                      messageAsDictionary:dict];
[self.commandDelegate pluginResult callbackId:command.callbackId];
*/
//  如果call back 是異步調(diào)用,要
// [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];

}

*Android

package cordova.plugin.netspay;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class NetsPay extends CordovaPlugin {

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (action.equals("requestPay")) {
            String message = args.getString(0);
            this. requestPay(message, callbackContext);
            return true;
        }
        return false;
    }

    private void requestPay(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) {
            callbackContext.success(message);
        } else {
            callbackContext.error("Expected one non-empty string argument.");
        }
    }
}

到此一個(gè)cordova plugin 就完成了

添加

  • 建議先在本地使用, 因?yàn)楸镜匕惭b時(shí),如果寫得有問(wèn)題, 會(huì)安裝提示失敗及原因. 最后測(cè)試沒(méi)問(wèn)題再Push 到github .
  • 可以把寫好plugin 放在與測(cè)試工程同一級(jí)下, 執(zhí)行:


cordova plugin add ../cordova-plugin-netspay(插件文件夾名, 要讓他能夠找到plugin.xml 文件) 

如果你已經(jīng)push 到github 可以執(zhí)行

cordova plugin add github地址 --variable GEOLOCATION_USAGE_DESCRIPTION ="寫上你想在xcode info.plist文件中對(duì)應(yīng)key的value"

添加成功后.

使用

// cordova.plugins.netspay 這個(gè)名字是由
/*
  <js-module src="www/netspay.js" name="netspay">
    <clobbers target="cordova.plugins.netspay" />
  </js-module>
  clobbers中的target 來(lái)的
*/
 try {
    (<any>window).cordova.plugins.netspay.requestPay({"hmac": "hmacfdsff3424"},
        (s) => {
          console.log('callback requestPay success', s);
        }, err => {
          console.log('callback requestPay err', err);
    })
  } catch (exception) {
         console.log(' open requestPay error ', exception);
  }

到此, 我們的cordova plugin 就創(chuàng)建結(jié)束, 如果想看關(guān)于swift怎么創(chuàng)建cordova插件, 請(qǐng)看我的另一篇文章:創(chuàng)建swift 版本的 cordova 插件,它會(huì)多幾個(gè)注意點(diǎn), 其實(shí)就是語(yǔ)法不同導(dǎo)致的.

補(bǔ)允: 如果是app 的使用者, 想添加pod ,可以在config.xml 中做以下配置 , ref

  <platform name="ios">
        <!-- set platform :ios, defaults to 7.0 -->
        <preference name="pods_ios_min_version" value="8.0"/>
        <!-- add use_frameworks! to Podfile, this also disabled bridging headers -->
        <preference name="pods_use_frameworks" value="true"/>
        <!-- use the latest version of a pod -->
        <pod name="LatestPod" />
        <!-- use a specific version of a pod -->
        <pod name="VersionedPod" version="1.0.0" />
        <!-- use a custom repo -->
        <pod name="GitPod1" git="https://github.com/blakgeek/something" tag="v1.0.1" />
        <pod name="GitPod2" git="https://github.com/blakgeek/something" branch="wood" />
        <pod name="GitPod3" git="https://github.com/blakgeek/something" commit="1b33368" />
        <!-- target specific configurations, this can be combined with all other options -->
        <pod name="GitPod2" configuration="debug" />
        <pod name="GitPod2" configurations="release,debug" />
        <!-- add a pod dependency using a custom podspec -->
        <pod name="GitPod2" podspec="https://example.com/JSONKit.podspec" />
        <!-- add a pod dependency using the spec parameter like a Cordova framework -->
        <pod name="GitPod2" spec="~> 2.0.0"/>
        <pod name="GitPod2" spec=":configurations => ['Debug', 'Beta']"/>
        <!-- if pod uses a bundle that isn't compatible with Cocoapods 1.x -->
        <pod name="BadBundle" fix-bundle-path="Bad/Path.bundle"/>
    </platform>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 用到的組件 1、通過(guò)CocoaPods安裝 2、第三方類庫(kù)安裝 3、第三方服務(wù) 友盟社會(huì)化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 15,159評(píng)論 1 180
  • 記得半年前假期開(kāi)始,就給自己定下把一年來(lái)的讀書(shū)筆記分類整理出來(lái),并開(kāi)始記錄自己的工作、學(xué)習(xí)心得。每次靜下來(lái)...
    默然相守寂靜歡喜閱讀 603評(píng)論 2 6
  • 任火華重新回到教學(xué)樓的時(shí)候,學(xué)生們已經(jīng)都走光了,教學(xué)樓的大門也已經(jīng)被鎖上。任火華看著陷入一片死寂的這棟樓,心里升騰...
    糖糖君閱讀 357評(píng)論 2 3
  • 記得小的時(shí)候,七八九歲的年紀(jì),一個(gè)小女生跟著鄰居家的小孩子圍著滿院子跑,大晚上,手上拿著各自的裝備武器,也就是些...
    會(huì)飛的二傻子閱讀 396評(píng)論 0 1
  • 1、線性表簡(jiǎn)介 在程序中,經(jīng)常需要將一組(通常是同為某個(gè)類型的)數(shù)據(jù)元素作為整體管理和使用。最簡(jiǎn)單的解決方案便是將...
    一把貓糧閱讀 927評(píng)論 0 0

友情鏈接更多精彩內(nèi)容