天天看點

#DAYU200#DAYU + Neptune 雙核出擊,Open Harmony 3.2靈光初現?

老子過去曰

上善若水,無為而治

而鴻蒙開發卻洪水滔天,津波浸地,

究竟誰可挺身而出,誰迎戰流年水逆?

今天的主角:DAYU + Neptune

大禹 + 海王

終極治水王霸 or 摸魚吹水冠軍?

5月末,Open Harmony 3.2釋出,随我一探深淺!

話說到我的自制無線遙控打蒜器實作以後,一直被HarmonyOS蝸牛般的釋出節奏以及Java與JS的繁瑣互動所限,表面看起來挺好玩,實則技術債苦不堪言,深感無奈。

51CTO和潤和軟體的老師們很貼心,榮幸當上==Dayu200體驗官==,硬體到手,不過一直對配套的OH3.1的api 8心存疑慮,根據以往的經驗,大的改進上沒有吹水,但是api本身存在各種bug,就我這個小項目而言極有可能又遭遇大困難,是以一直在看大佬們的文章學習。

好在皇天不負有心人,就在前天,試探性地刷了下新出爐的Open Harmony 3.2 beta,嘗試了下測試中的api

9,驚喜來了,成果請看視訊:智能打蒜器。

Neptune的嵌入和編碼,以及HarmonyOS上基于JS的App開發不再重複,請看自制無線遙控打蒜器。

Open Harmony的版本的變化是App上的,從之前的Java和JS橋接,差不多近200多行非常費解的代碼。自從3.2大部分實作Socket協定後,減少到不到20行以内,無需再寫任何Java的Ability。

App隻有一個頁面,index.ets,代碼如下:

import socket from '@ohos.net.socket'
import wifi from '@ohos.wifi';
import { resolveIP } from './util'
import prompt from '@ohos.prompt';

let udp = socket.constructUDPSocketInstance()
let port = 63060


let localAddr = {
  address: resolveIP(wifi.getIpInfo().ipAddress),
  port: port
}

let mixerAddr = {
//  address: '255.255.255.255', //區域網路關播位址
  address: '192.168.2.6', //打蒜器位址
  port: port
}


@Entry
@Component
struct Index {
  @State connected: boolean = false
  @State on: boolean = false

  build() {
    Stack() {
      Column() {
        Column().height(100)
        Text('智能打蒜器')
          .fontSize(60)
          .fontWeight(FontWeight.Lighter)
          .fontColor(Color.White)
        Text(this.connected ? '已連接配接' : '未連接配接')
          .fontSize(30)
          .fontWeight(FontWeight.Lighter)
          .fontColor(Color.White)
        Text(this.on ? '運作中' : '')
          .fontSize(30)
          .fontWeight(FontWeight.Lighter)
          .fontColor(Color.White)
        Blank()

        Stack() {
          Image($r("app.media.panel2"))
            .height('100%')
            .width('100%')
            .objectFit(ImageFit.Fill)
          Image(this.connected ?
          $r("app.media.switch_red") :
          $r("app.media.switch_blue"))
            .width(120)
            .objectFit(ImageFit.Contain)
            .aspectRatio(1)
        }
        .height(180)
        .width('100%')

      }
      .width('100%')
      .height('100%')
      .backgroundColor(this.connected ? '#F2A6A6' : '#71A9FE')

      Image(this.on ? $r("app.media.on") : $r("app.media.off"))
        .objectFit(ImageFit.Contain)
        .onClick(() => {
          this.sendData()
        })
    }
    .width('100%')
    .height('100%')
    .onAppear(() => {
      this.bindOptions()
    })
  }

  bindOptions() {
    console.log('==Init,local IP is:' + JSON.stringify(localAddr))

    udp.bind(localAddr, e => {
      if (e) {
        console.log('==bind error')
        return
      }
      console.log('==bind ok')

      udp.setExtraOptions({
        broadcast: true
      }, e => {
        if (e) {
          console.log('==set extra option broadcast failed:' + JSON.stringify(e))
          return
        }

        console.log('setExtraOptions success');
      })

    })

    udp.on('listening', () => {
      console.log("==on listening success");
    })

    udp.on('message', data => { //收到指定端口來的消息
      this.connected = true //連接配接成功!
      console.log("==on message!")

      let dataView = new DataView(data.message)

      let str = ""
      for (let i = 0;i < dataView.byteLength; ++i) {
        let c = String.fromCharCode(dataView.getUint8(i))
        if (c !== "\n") {
          str += c
        }
      }
      console.log("==message:" + str + "From:" + data.remoteInfo.address)
      mixerAddr.address = data.remoteInfo.address //更新打蒜器的位址

    })
  }

  async checkOnline(){
    try {
      await udp.send({ data: 'check',address: mixerAddr})
      this.connected = true

      console.log(`==Send check ok >:  + ${mixerAddr.address}`)

    } catch (e){
      console.log('==Error send: ' + e)
    }
  }

  async sendData() {
    await this.checkOnline()
    if (!this.connected) {
      prompt.showToast({
        message: '暫未連接配接!'
      })
      return
    }
    let order = '' //開關指令
    if (this.on) { //如果是開,則發送關;
      order = 'of'
    } else {
      order = 'on'//關則發送開。
    }

    try {

      await udp.send({ data: order,address: mixerAddr})
      this.on = !this.on

      console.log(`==Send ${order} >:  + ${mixerAddr.address}`)

    } catch (e){
      console.log('==Error send: ' + e)
    }

  }
}
           

輔助工具類 util.ets:

export function resolveIP(ip) {
  if(ip < 0 || ip > 0xFFFFFFFF){
    throw ("The number is not normal!");
  }
  return (ip>>>24) + "." + (ip>>16 & 0xFF) + "." + (ip>>8 & 0xFF) + "." + (ip & 0xFF);
}
           

其中需要注意的是, 目前Open Harmony 3.2中的Socket并不支援發送資料廣播,而且也無法收到廣播資訊,應該是從api上内部屏蔽了或者有bug,我沒看源碼,懂的大佬還請指正。

這個過程最愉快的是,Open Harmony支援Dayu200這樣的富裝置後,可以随心所欲的進行修改、優化,不再有任何HarmonyOS上那樣的限制,更新速度按周計算,大大提升了疊代速度,測試速度更快。真正成為了一套普通開發者也可以比較容易輕松定制的全能OS。 也期待潤和和其他生态廠商能帶給我們更快、更小的各種開發闆,

有了Dayu200和Open Harmony 3.2,我不是要想說Java要如何結束,

而是告訴你如何開始,一個沒有邊界、沒有限制,一個有任何可能的鴻蒙世界。

繼續閱讀