今天我正在debug,突然發現郭霖更新了(於是就開始快樂摸魚),哈哈哈。不知道大家看見沒有。下面分享一下,希望對大家的工作和學習有些幫助。
/ 今日科技快訊 /
近日,字節跳動迴應:由美國CFIUS調查及“總統令”引發對TikTok的大量關注與報道,其中有很多猜測和不實信息。真實情況是, 我們確實在與一些公司探討合作方案,以解決美國政府與公衆對於美國用戶數據安全的顧慮,上述方案不涉及業務和技術出售,也尚未簽署最終協議。最終協議的簽署,還需依據法律獲得中國和美國相關部門的批准。
/ 作者簡介 /
明天就是週末,大家注意好好休息哦~
本篇文章來自傷心的豬大腸的投稿,和大家分享了他對華爲鴻蒙系統使用的一些內容整理,相信會對大家有所幫助!同時也感謝作者貢獻的精彩文章!
傷心的豬大腸的博客地址:
/ 前言 /
2020年9月10號,鴻蒙2.0(HarmonyOS 2.0)系統正式發佈,鴻蒙2.0面向應用開發者發佈Beta版本,在2020年9月10發佈大屏,手錶,車機版鴻蒙,2020年12月發佈手機版鴻蒙。在2020年9月10日,鴻蒙開源路標面向內存128KB-128MB終端設備;2021年10月,將面向4GB以上所有設備。
/ 背景 /
作爲一個安卓開發者,能夠看到國產的操作系統的發佈確實很興奮,興奮之餘,更想要看看具體是怎麼一回事,首先打開官網,看看官網該系統的定義:HarmonyOS是一款“面向未來”、面向全場景(移動辦公、運動健康、社交通信、媒體娛樂等)的分佈式操作系統。在傳統的單設備系統能力的基礎上,HarmonyOS提出了基於同一套系統能力、適配多種終端形態的分佈式理念,能夠支持多種終端設備。
對應用開發者而言,HarmonyOS採用了多種分佈式技術,使得應用程序的開發實現與不同終端設備的形態差異無關,降低了開發難度和成本。這能夠讓開發者聚焦上層業務邏輯,更加便捷、高效地開發應用。該優點在5G這個萬物互聯的時代具有着巨大的優勢。
/ 安裝DevEco Studio /
接下來下載DevEco Studio(IDE/開發工具)來進行體驗一下軟件的開發,在這裏可以看到目前的IDE只有Windows系統的(windows 10 64位),安裝過程可能中會出現gradle的安裝失敗,記得添加代理,在用戶目錄(打開“此電腦”,在文件夾地址欄中輸入%userprofile%,進入個人數據界面。)下創建gradle.properties文件,文件中添加,端口是代理的端口。
systemProp.https.proxyPort=63729
systemProp.http.proxyHost=127.0.0.1
systemProp.https.proxyHost=127.0.0.1
systemProp.http.proxyPort=63729
gradle安裝成功,但在編譯過程中可能出現build失敗,錯誤如下:
ERROR: Cause: mirrors.huaweicloud.com:443 failed to respond
解決方式就是把所有的代理先關掉,然後你就會發現如絲般順滑。安裝完DevEco Studio後,打開後可以看到界面和Android Studio非常相似。
佈局開發
一切看起來非常的熟悉,可以使用Java或JS等語言進行開發,佈局可以通過XML創建,size單位是vp。
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="vertical"
ohos:padding="32">
<Text
ohos:id="$+id:text"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="horizontal_center"
ohos:text="My name is Jackie."
ohos:text_size="25vp"/>
<Button
ohos:id="$+id:button"
ohos:width="match_content"
ohos:height="match_content"
ohos:layout_alignment="horizontal_center"
ohos:text="My name is Jackie."
ohos:text_size="50"/>
</DirectionalLayout>
也可以通過Java代碼直接創建,點擊事件都是如此的親切。
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// 步驟1 聲明佈局
DirectionalLayout directionalLayout = new DirectionalLayout(context);
// 步驟2 設置佈局大小
directionalLayout.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
directionalLayout.setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
// 步驟3 設置佈局屬性及ID(ID視需要設置即可)
directionalLayout.setOrientation(Component.VERTICAL);
directionalLayout.setPadding(32, 32, 32, 32);
Text text = new Text(context);
text.setText("My name is Text.");
text.setTextSize(50);
text.setId(100);
// 步驟4.1 爲組件添加對應佈局的佈局屬性
DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(LayoutConfig.MATCH_CONTENT,
LayoutConfig.MATCH_CONTENT);
layoutConfig.alignment = LayoutAlignment.HORIZONTAL_CENTER;
text.setLayoutConfig(layoutConfig);
// 步驟4.2 將Text添加到佈局中
directionalLayout.addComponent(text);
// 類似的添加一個Button
Button button = new Button(context);
layoutConfig.setMargins(0, 50, 0, 0);
button.setLayoutConfig(layoutConfig);
button.setText("My name is Jackie.");
button.setTextSize(50);
button.setId(100);
ShapeElement background = new ShapeElement();
background.setRgbColor(new RgbColor(0, 125, 255));
background.setCornerRadius(25);
button.setBackground(background);
button.setPadding(10, 10, 10, 10);
button.setClickedListener(new Component.ClickedListener() {
@Override
// 在組件中增加對點擊事件的檢測
public void onClick(Component Component) {
// 此處添加按鈕被點擊需要執行的操作
}
});
directionalLayout.addComponent(button);
// 步驟5 將佈局作爲根佈局添加到視圖樹中
super.setUIContent(directionalLayout);
}
首頁的佈局如下,通過Java代碼創建。
@Override
public void onStart(Intent intent) {
super.onStart(intent);
System.out.println("onStart");
LayoutConfig config = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT);
myLayout.setLayoutConfig(config);
ShapeElement element = new ShapeElement();
element.setRgbColor(new RgbColor(255, 255, 255));
myLayout.setBackground(element);
Text text = new Text(this);
text.setLayoutConfig(config);
text.setText("CT Jackie");
text.setTextColor(new Color(0xFF000000));
text.setTextSize(50);
text.setTextAlignment(TextAlignment.CENTER);
myLayout.addComponent(text);
super.setUIContent(myLayout);
}
效果如下
[圖片上傳失敗...(image-b04f4e-1600698132343)]
生命週期
下面再來看看主界面的生命週期,實現了ILifecycle接口,生命週期狀態一共有七種。
public static enum Event {
UNDEFINED,
ON_START,
ON_INACTIVE,
ON_ACTIVE,
ON_BACKGROUND,
ON_FOREGROUND,
ON_STOP;
private Event() {
}
}
界面啓動時調用onStart()和onActive()。
2020-09-13 21:42:10.266 25547-25547[表情] I/System.out: onStart
2020-09-13 21:42:10.284 25547-25547[表情] I/System.out: onActive
點擊返回鍵時調用。
2020-09-13 21:42:35.847 25547-25547/com.example.helloworld I/System.out: onInactive
2020-09-13 21:42:35.917 25547-25547/com.example.helloworld I/System.out: onBackground
2020-09-13 21:42:35.920 25547-25547/com.example.helloworld I/System.out: onStop
至於UNDEFINED和ON_FOREGROUND暫時還不瞭解。
Gradle任務(Task)
甚至連gradle的Task都非常類似,打包命令是assembleDebug/Release。
> Task :entry:preBuild
> Task :entry:compileDebugNativeWithCmake
> Task :entry:collectDebugDependencies
> Task :entry:mergeDebugResources
> Task :entry:mergeDebugProfile
> Task :entry:compileDebugResources
> Task :entry:compileDebugIdl
> Task :entry:compileDebugRFile
> Task :entry:processDebugJavaResource
> Task :entry:compileDebugJavaWithJavac
> Task :entry:mergeDebugJavaResource
> Task :entry:generateDebugClassesJar
> Task :entry:mergeDebugProjectDex
> Task :entry:generateDebugShell
> Task :entry:processDebugShellManifest
> Task :entry:compileDebugShellResources
> Task :entry:linkDebugShellResources
> Task :entry:compileDebugShellJavaWithJavac
> Task :entry:mergeDebugShellDex
> Task :entry:packageDebugShell
> Task :entry:packageDebugSimplifyShell
> Task :entry:validateDebugSigning
> Task :entry:signDebugShell
> Task :entry:packageDebugHap
> Task :entry:signDebugHap
> Task :entry:assembleDebug
配置文件
配置文件是一個命名爲config.json的文件,配置應用的一些信息。
{
"app": {
"bundleName": "com.example.helloworld",
"vendor": "example",
"version": {
"code": 1,
"name": "1.0"
},
"apiVersion": {
"compatible": 3,
"target": 3
}
},
"deviceConfig": {
"default": {
}
},
"module": {
"package": "com.example.helloworld",
"name": ".HelloWorld",
"reqCapabilities": [
"video_support"
],
"deviceType": [
"wearable"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry"
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "landscape",
"formEnabled": false,
"name": "com.example.helloworld.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "HelloWorld",
"type": "page",
"launchType": "standard"
}
]
}
}
仔細看這個文件會越來越覺得這就是AndroidManifest.xml的json翻譯版。
/ 反編譯角度看鴻蒙 /
既然看起來這麼像安卓,我看來看看它編譯後的產物是什麼,是不是也能像android一樣反編譯得到dex文件?
編譯後得到的是一個xxx.hap文件。
修改它的後綴名爲.zip,解壓後可以看到裏面有熟悉的assets,dex,apk文件等,把這個apk文件安裝後發現並不能使用。
[圖片上傳失敗...(image-ec3f51-1600698132343)]
下面我們先反編譯這個classes.dex文件第一個dex反編譯後出現錯誤。
~/Desktop/fanbianyi/dex2jar-2.0 » sh d2j-dex2jar.sh classes3.dex
dex2jar classes3.dex -> ./classes3-dex2jar.jar
com.googlecode.d2j.DexException: not support version.
at com.googlecode.d2j.reader.DexFileReader.<init>(DexFileReader.java:151)
at com.googlecode.d2j.reader.DexFileReader.<init>(DexFileReader.java:211)
at com.googlecode.dex2jar.tools.Dex2jarCmd.doCommandLine(Dex2jarCmd.java:104)
at com.googlecode.dex2jar.tools.BaseCmd.doMain(BaseCmd.java:288)
at com.googlecode.dex2jar.tools.Dex2jarCmd.main(Dex2jarCmd.java:32)
原因是我們的工具版本太低了,解決方案就是升級,升級版本後反編譯成功後爲classes3-dex2jar.jar,打開可以看到:
這裏多了個ResourceTable文件,就是我們的資源id表。這裏的dex文件包含的是我們開發的代碼。
下面我們來反編譯apk文件,解壓後可以看到,裏面是我們熟悉的內容:
AndroidManifest.xml文件如下:
反編譯該dex文件可以看到,MainAbilityShellActivity最終是繼承了AbilityShellActivity:
ShellHelloWorld其實一個Application。
至此感覺.hap文件像是對apk的一個包裝,最終的邏輯看起來好像還是android那套,或者說android開發人員上手會非常快,可能也是爲將來兼容android系統做準備。
/ 分佈式,跨設備遷移 /
跨設備遷移
下面來看看該系統的一些亮點,比如跨設備遷移,聽起來是個很牛逼炫酷的功能,比如把你的手機屏幕直接遷移到電腦或者pad上面以及進行一些操作等等。
跨設備遷移(下文簡稱“遷移”)支持將Page在同一用戶的不同設備間遷移,以便支持用戶無縫切換的訴求。以Page從設備A遷移到設備B爲例,遷移動作主要步驟如下:
- 設備A上的Page請求遷移。
- HarmonyOS處理遷移任務,並回調設備A上Page的保存數據方法,用於保存遷移必須的數據。
- HarmonyOS在設備B上啓動同一個Page,並回調其恢復數據方法。
開發者可以參考以下詳細步驟開發具有遷移功能的Page。
分佈式任務調度
在HarmonyOS中,分佈式任務調度平臺對搭載HarmonyOS的多設備構築的“超級虛擬終端”提供統一的組件管理能力,爲應用定義統一的能力基線、接口形式、數據結構、服務描述語言,屏蔽硬件差異;支持遠程啓動、遠程調用、業務無縫遷移等分佈式任務。
分佈式任務調度平臺在底層實現Ability。
- 啓動和關閉:向開發者提供管理遠程Ability的能力,即支持啓動Page模板的Ability,以及啓動、關閉Service和Data模板的Ability。
- 連接和斷開連接:向開發者提供跨設備控制服務(Service和Data模板的Ability)的能力,開發者可以通過與遠程服務連接及斷開連接實現獲取或註銷跨設備管理服務的對象,達到和本地一致的服務調度。
- 遷移能力:向開發者提供跨設備業務的無縫遷移能力,開發者可以通過調用Page模板Ability的遷移接口,將本地業務無縫遷移到指定設備中,打通設備間壁壘。
/ 總結 /
個人感覺鴻蒙的開發是很接近Android開發者的習慣,對於Android開發人員來說極易上手,但是Android現有的多設備協同支持做的很差,鴻蒙做了一些封裝和擴展屏蔽掉底層的差異,在多設備,萬物互聯的時代具有很大的優勢,越是多設備協同,鴻蒙越具有優勢。
開源項目地址:https://github.com/xieyuliang/Note-Android ,裏面有很多有用的技術文,還有很多Android高級架構師進階學習資料,有需要的朋友自取。
原文地址:鴻蒙開發初體驗
進取不止,代碼之外,再無世界!Android開發者們,你我共勉!