安卓VS鴻蒙第三方件切換寶典 V1.0
眾所周知,安卓應用開發經過這么多年的發展相對成熟和穩定,鴻蒙OS作為后來者兼容一個成熟的開發體系會節省很多推廣和開發成本。但在實際開發中,代碼層面仍然有很多細節上的差異,會給初次開發人員造成困擾。
本寶典旨在匯總實際開發中第三方件接入時的代碼差異,以期幫助開發人員更好的進行開發作業,由于目前接觸的開發類型有限,所匯總的內容多少會有疏漏,后期我們會進一步完善和補全。
歡迎關注我們以及我們的專欄,方便您及時獲得相關內容的更新。
※基礎功能
1.獲取屏幕分辨率
安卓:
- getWindowManager().getDefaultDisplay();
鴻蒙:
- Optional<Display>
- display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
- Point pt = new Point();
- display.get().getSize(pt);
2.隱藏標題欄TitleBar
安卓:
略
鴻蒙:
confi.json中添加如下描述:
- ""metaData"":{
- ""customizeData"":[
- {
- ""name"": ""hwc-theme"",
- ""value"": ""androidhwext:style/Theme.Emui.NoTitleBar"",
- ""extra"":""""
- }
- ]
- }
3.獲取屏幕密度
安卓:
- Resources.getSystem().getDisplayMetrics().density
鴻蒙:
- // 獲取屏幕密度
- Optional<Display>
- display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
- DisplayAttributes displayAttributes = display.get().getAttributes();
- //displayAttributes.xDpi;
- //displayAttributes.yDpi;
4.獲取上下文
安卓:
- context
鴻蒙:
- getContext()
5.組件的父類
安卓:
- android.view.View; class ProgressBar extends View
鴻蒙:
- class ProgressBar extends Component
6.沉浸式顯示
安卓:
略
鴻蒙:
A:在config.json ability 中添加
- "metaData"": {
- ""customizeData"": [
- {
- ""extra"": """",
- ""name"": ""hwc-theme"",
- ""value"": ""androidhwext:style/Theme.Emui.Light.NoTitleBar""
- }
- ]
- }
B:在AbilitySlice的onStart函數內增加如下代碼,注意要在setUIContent之前。
- getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
7.獲取運行時權限
安卓:
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1)
鴻蒙:
- requestPermissionsFromUser(
- new String[]{""ohos.permission.READ_MEDIA"", ""ohos.permission.WRITE_MEDIA"", ""ohos.permission.READ_USER_STORAGE"", ""ohos.permission.WRITE_USER_STORAGE"",}, 1);
※布局&組件
1.頁面跳轉(顯示跳轉)
安卓:
A.從A跳轉至B,沒有參數,并且不接收返回值
- Intent intent = new Intent();
- intent.setClass(A.this, B.class);
- startActivity(intent);
B.從A跳轉至B,有參數,不接收返回值
- Intent intent = new Intent(this, B.class);
- intent.putExtra(""name"", ""lily"");
- startActivity(intent);
C.從A跳轉至B,有參數,接收返回值
- Intent intent = new Intent(this, B.class);
- intent.putExtra(""name"", ""lily"");
- startActivityForResult(intent, 2);
鴻蒙:
A.從A跳轉至B,沒有參數,并且不接收返回值
- present(new BSlice(), new Intent());
B.從A跳轉至B,有參數,不接收返回值
- Intent intent = new Intent();
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId("""") .withBundleName(""com.test"") .withAbilityName(""com.test.BAbility"")
- .build();
- intent.setParam(""name"",""lily"");
- intent.setOperation(operation);
- startAbility(intent);
C.從A跳轉至B,有參數,接收返回值
- Intent intent = new Intent();
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId("""") .withBundleName(""com.test"") .withAbilityName(""com.test.BAbility"")
- .build();
- intent.setParam(""name"",""lily"");
- intent.setOperation(operation);
- startAbilityForResult(intent,100);
2.頁面跳轉(隱式跳轉)
安卓:
A.配置
- <activity android:name="".B"">
- <intent-filter>
- <action android:name=""com.hly.view.fling""/>
- </intent-filter>
- </activity>
B.啟動
- Intent intent = new Intent(); intent.setAction(""com.hly.view.fling""); intent.putExtra(""key"", ""name""); startActivity(intent);
鴻蒙:
A.在config.json文件ability 中添加以下信息
- "skills"":[
- {
- ""actions"":[
- ""ability.intent.gotopage""
- ]
- }
- ]
B.在MainAbility的onStart函數中,增加頁面路由
- addActionRoute( ""ability.intent.gotopage"", BSlice.class.getName());
C.跳轉
- Intent intent = new Intent();
- intent.setAction(""ability.intent.gotopage"");
- startAbility(intent);
3.頁面碎片
安卓:
- Fragment
鴻蒙:
- Fraction
A:Ability繼承FractionAbility
B:獲取Fraction調度器
- getFractionManager().startFractionScheduler()
C:構造Fraction
D:調用調度器管理Fraction
- FractionScheduler.add()
- FractionScheduler.remove()
- FractionScheduler.replace()
備注:
參考demo
https://www.jianshu.com/p/58558dc6673a"
4.從xml文件創建一個組件實例
安卓:
- LayoutInflater.from(mContext).inflate(R.layout.banner_viewpager_layout, null);
鴻蒙:
- LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_ability_main, null, false);
5.組件自定義繪制
安卓:
- ImageView.setImageDrawable(Drawable drawable);
并重寫Drawable 的draw函數
鴻蒙:
- Component.addDrawTask(Component.DrawTask task);
并實現Component.DrawTask接口的onDraw函數
6.自定義組件的自定義屬性(在xml中使用)
安卓:
需要3步
A.在 values/attrs.xml,在其中編寫 styleable 和 item 等標簽元素。
B.在layout.xml中,增加
- xmln:app= ""http://schemas.android.com/apk/res/-auto""
C.在自定義組件的構造函數中,調用array.getInteger(R.styleable.***, 100);獲取屬性
鴻蒙:
只需2步
A. 在組件定義的layout.xml中增加 xmlns:app=""http://schemas.huawei.com/apk/res/ohos""
然后就可以使用app:***(***為任意字符串)來增加自定義屬性了,為了區分建議加上組件名前綴。
B. 在自定義組件的帶AttrSet參數的構造函數中,使用下面代碼獲取屬性。attrSet.getAttr(""***"").get().getStringValue();
7.觸摸事件
安卓:
- android.view.MotionEvent
鴻蒙:
- ohos.multimodalinput.event.TouchEvent
8.事件處理
安卓:
- android.os.Handler
鴻蒙:
- ohos.eventhandler.EventHandler
9.控件觸摸事件回調
安卓:
- android.view.View.OnTouchListener
鴻蒙:
- ohos.agp.components.Component.
- TouchEventListener
10.輪播圖繼承的父類
安卓:
- extends ViewPager
鴻蒙:
- extends PageSlider
11.實現監聽輪播圖組件事件
安卓:
- implements PageSlider.PageChangedListener
鴻蒙:
- Implements OnPageChangedListener
12.touch事件監聽
安卓:
- 直接重寫onTouchEvent
鴻蒙:
- 繼承 Component.TouchEventListener然后在構造方法中設置監聽 setTouchEventListener(this::onTouchEvent);實現onTouchEvent
13.獲取點擊事件的坐標點
安卓:
- event.getX(), event.getY()
鴻蒙:
- MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
14.調節滾輪中內容間距
安卓:
- setLineSpacingMultiplier(float f)
鴻蒙:
- setSelectedNormalTextMarginRatio(float f)
15.滾輪定位
安卓:
- setPosition
鴻蒙:
- setValue
16.Layout布局改變監聽
安卓:
- View.OnLayoutChangeListener
鴻蒙:
- Component.LayoutRefreshedListener
17.組件容器
安卓:
- ViewGroup
鴻蒙:
- ComponentContainer
18.添加組件
安卓:
- addView()
鴻蒙:
- addComponent()
19.動態列表的適配器
安卓:
- extends RecyclerView.Adapter<>
鴻蒙:
- extends RecycleItemProvider
20.動態列表
安卓:
- RecyclerView
鴻蒙:
- ListContainer
21.文本域動態監聽
安卓:
- TextWatcher
鴻蒙:
- Component.ComponentStateChangedListener
22.組件繪制自定義布局
安卓:
- 重寫onLayout(boolean changed, int left, int top, int right, int bottom)
鴻蒙:
- 重寫Component.LayoutRefreshedListener的onRefreshed方法
23.List組件
安卓:
- ListView
鴻蒙:
- ListContainer
24.設置背景顏色
安卓:
- setBackgroundColor(maskColor);
鴻蒙:
- // 創建背景元素
- ShapeElement shapeElement = new ShapeElement();
- // 設置顏色
- shapeElement.setRgbColor(new RgbColor(255, 0, 0));
- view.setBackground(shapeElement);
25.可以在控件上、下、左、右設置圖標,大小按比例自適應
安卓:
- setCompoundDrawablesWithIntrinsicBounds
鴻蒙:
- setAroundElements
26.RadioButton組件在xml中如何設置checked屬性
安卓:
在xml中可以設置
鴻蒙:
- radioButton = findComponentById();
- radioButton.setChecked(true);
備注:
sdk2.0后 xml中沒有了checked屬性,如果使用,可以在java代碼中實現"
27.文本域動態監聽
安卓:
- TextWatcher
鴻蒙:
- Component.ComponentStateChangedListener
28.顏色類
安卓:
- java.awt.Color
鴻蒙:
- ohos.agb.colors.rgbcolor
29.為ckeckbox或者Switch按鈕設置資源圖片
安卓:
略
鴻蒙:
- VectorElement vectorElement = new VectorElement(this, ResourceTable.Graphic_candy);
- setBackground(vectorElement)
30.子組件將拖拽事件傳遞給父組件
安卓:
略
鴻蒙:
注冊setDraggedListener偵聽,實現onDragPreAccept方法,再方法內根據拖拽方向判斷是否需要父組件處理,如果需要則返回false,否則返回true
※資源管理
1.管理資源
安卓:
- AssertManager
鴻蒙:
- ResourceManager
2.獲取應用的資源文件rawFile,并返回InputStream
安卓:
- getResources()
- AssetManager類
鴻蒙:
- ResourceManager resourceManager = getContext().getResourceManager();
- RawFileEntry rawFileEntry = resourceManager.getRawFileEntry(jsonFile);
- Resource resource = null;
- try {
- resource = rawFileEntry.openRawFile();
- } catch (IOException e) {
- e.printStackTrace();
- }
備注:
- Resource是InputStream的子類,可以直接作為InputStream使用。"
3.獲取文件路徑
安卓:
- Environment.getExternalStorageDirectory().getAbsolutePath()
鴻蒙:
- 獲取文檔(DIRECTORY_DOCUMENTS)、下載(DIRECTORY_DOWNLOADS)、視頻(DIRECTORY_MOVIES)、音樂(DIRECTORY_MUSIC)、圖片(DIRECTORY_PICTURES)
- GetExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath()
※消息&多線程
1.事件循環器
安卓:
- android.os.Looper
鴻蒙:
- EventRunner.create(true)
備注:
有參數且為true,表示隊列被托管,參數為false,或無參表示不被托管,需要eventRunner.run()調用
2.消息
安卓:
- android.os.Message
鴻蒙:
- InnerEvent
3.休眠
安卓:
- android.os.SystemClock.sleep()
鴻蒙:
- ohos.miscservices.timeutility.time;
- Time.sleep(int millesend)
4.事件通知延遲消息
安卓:
- Handler.postDelayed(MESSAGE_LOGIN, 5000);
鴻蒙:
- Handler.postTask(task, 5000);
5.Intent傳遞參數
安卓:
- Intent.putExtra or add Bundle
鴻蒙:
- Intent.setParam
6.消息發送
安卓:
- Handler handler = new Handler,通過handlerMsg發消息
鴻蒙:
- InnerEvent event1 = InnerEvent.get(eventId1, param, object);
- myHandler.sendEvent(event1, 0, Priority.IMMEDIATE);
7.更新UI
安卓:
- class MyHandle extends Handler{
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- switch (msg.what) {
- case 1:
- //更新UI的操作
- break;
- default:
- Break;
- }
- }
- }
鴻蒙:
- abilitySlice.getUITaskDispatcher().asyncDispatch(() -> {
- //更新UI的操作
- });
※圖片處理
1.位圖資源
安卓:
- Bitmap
鴻蒙:
- PixelMap
2.圖像縮放,拉伸到視圖邊界
安卓:
- ImageView.ScaleType
- image.setScaleType(ScaleType.FXY);
鴻蒙:
- Image.ScaleMode
- image.setScaleMode(Image.ScaleMode.STRETCH);
3.List組件&內容適配器
安卓:
- ListView
- extends BaeAdapter
- ViewPage.setAdapter(BaeAdapter);
鴻蒙:
- ListContainer
- extends PageSlider
- PageSlider.setProvider(PageSlider);
4.圖片顯示組件
安卓:
- androidx.appcompat.widget.AppCompatImageView
- Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),drawableId);
- Image.setImageBitmap(bitmap);
鴻蒙:
- ohos.agp.components.Image
根據實際情況可傳遞其他參數
- ImageSource imageSource = ImageSource.create(file, new ImageSource.SourceOptions());
- pixelMap = imageSource.createPixelmap(new ImageSource.DecodingOptions());
- image.setPixelMap(pixelMap);
5.圖片填充整個控件
安卓:
- image.setScaleType(ScaleType.FXY);
鴻蒙:
- image.setScaleMode(Image.ScaleMode.STRETCH);
6.通過資源id獲取位圖
安卓:
- getBitmapFromDrawable
鴻蒙:
- /**
- * 通過資源ID獲取位圖對象
- **/
- private PixelMap getPixelMap(int resId) {
- InputStream drawableInputStream = null;
- try {
- drawableInputStream = getResourceManager().getResource(resId);
- ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
- sourceOptions.formatHint = ""image/png"";
- ImageSource imageSource = ImageSource.create(drawableInputStream, null);
- ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
- decodingOptions.desiredSize = new Size(0, 0);
- decodingOptions.desiredRegion = new Rect(0, 0, 0, 0);
- decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
- PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
- return pixelMap;
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (drawableInputStream != null) {
- drawableInputStream.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return null;
- }
7.獲取Gif圖片幀
安卓:
需要自定frame類,通過decoder獲取
鴻蒙:
- ImageSource.createPixelmap(int index, ImageSource.DecodingOptions opts)
8.BMP位圖裁剪
安卓:
- Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)
鴻蒙:
- PixelMap.create(PixelMap source, Rect srcRegion, PixelMap.InitializationOptions opts)
※視頻播放
在視頻播放窗口上層增加控件
安卓:
略
鴻蒙:
A.pinToTop設置false,保證其他控件與surfaceProvider在同一layout下,并且不能設置背景
B.增加以下代碼設置頂部窗口透明
- WindowManager.getInstance().getTopWindow().get().setTransparent(true);
※數據庫
數據庫獲取索引
安卓:
- android.database.Cursor;
- cursor.getString()/cursor.getColumnIndex()
鴻蒙:
- ohos.data.resultset
※數據結構
1.應用程序數據共享
安卓:
- context.getContentResolver();
- resolver.getType(uri)
鴻蒙:
- ohos.aafwk.ability.DataAbilityHelper
2.JSON解析
安卓:
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import org.json.JSONTokener;
鴻蒙:
- Gson,fastJson
3.對象序列化
安卓:
- android.os.Parcel;
- parcel.readParcelable();parcel.writeParcelable()
鴻蒙:
- ohos.utils.parcel
4.浮點數矩形,獲取中心點
安卓:
- RectF.centerX()
鴻蒙:
- RectFloat.getCenter().getPointX()
5.數據結構類
安卓:
- LongSparseArray
- SparseArrayCompat
鴻蒙:
使用HashMap
備注:
內存使用和查找性能會有影響。"
6.浮點數矩形
安卓:
- RectF
鴻蒙:
- RectFloat
7.浮點坐標
安卓:
- PointF
鴻蒙:
- 可使用Point
※對話框
1.對話框銷毀
安卓:
- mDialog.dismiss()
鴻蒙:
- mDialog.destroy();
2.對話框中加載布局
安卓:
- mDialog.setContentView(ViewGroup dialogView)
鴻蒙:
- setContentCustomComponent(Componnet comp)
3.點擊對話框外部關閉對話框
安卓:
- mDialog.setCancelable(mPickerOptions.cancelable)
鴻蒙:
- mDialog.setDialogListener(new BaseDialog.DialogListener() {
- @Override
- public boolean isTouchOutside() {
- mDialog.destroy(); dialogView.getComponentParent().removeComponent(dialogView);
- return true;
- }
- });
備注:
鴻蒙對話框銷毀之后需移除對話框中加載的布局,否則再次加載會報錯"
※動畫
1.旋轉動畫
安卓:
- android.view.animation.RotateAnimation
鴻蒙:
- ohos.agp.animation.AnimatorProperty
2.值動畫及相關回調
安卓:
- android.animation.ValueAnimator
- ValueAnimator.AnimatorUpdateListener
- Animator.AnimatorListener
- Animator.AnimatorPauseListener
鴻蒙:
- ohos.agp.animation.AnimatorValue
- AnimatorValue.ValueUpdateListener
- Animator.StateChangedListener
- Animator.LoopedListener
備注:
啟動動畫時,AnimatorValue必須作為類的成員變量,而不能時函數局部變量,否則動畫不會啟動"
3.線性插值器
安卓:
- LinearInterpolator
鴻蒙:
自己寫一個
- public interface Interpolator {
- float getInterpolation(float input);
- }
- public class LinearInterpolator implements Interpolator {
- public LinearInterpolator() {
- }
- public LinearInterpolator(Context context, AttrSet attrs) {
- }
- public float getInterpolation(float input) {
- return input;
- }
- }
4.設置動畫循環次數
安卓:
- animation.setRepeatCount(Animation.INFINITE)
鴻蒙:
- animator.setLoopedCount(Animator.INFINITE)
※存儲
獲取存儲根路徑
安卓:
- Environment.getExternalStorageDirectory().getAbsolutePath();
鴻蒙:
- System.getProperty("user.dir")
※Canvas繪圖
1.繪制圓弧
安卓:
- Android canvas.drawArc()
鴻蒙:
- ohos.agp.render; class Arc
2.繪制圓形的兩種方式
安卓:
- canvas.drawCircle(float x, float y, float radius, Paint paint)
鴻蒙:
- A.canvas.drawPixelMapHolderRoundRectShape(PixelMapHolder holder, RectFloat rectSrc, RectFloat rectDst, float radiusX, float radiusY)
- B.canvas.drawCircle(float x, float y, float radius, Paint paint)
3.繪制文本的方法
安卓:
- drawText (String text, float x, float y, Paint paint)
鴻蒙:
- drawText(Paint paint, String text, float x, float y)
4.獲取text 的寬度
安卓:
- text.getWidth();
鴻蒙:
- Paint paint = new Paint();
- paint.setTextSize(text.getTextSize());
- float childWidth = paint.measureText(text.getText());
歡迎交流:HWIS-HOS@isoftstone.com