国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android中利用動態加載實現手機淘寶的節日特效

2019-12-12 04:17:37
字體:
來源:轉載
供稿:網友

相信去年圣誕節打開過手機淘寶的童鞋都會對當時的特效記憶猶新吧:全屏飄雪,旁邊還有個小雪人來控制八音盒背景音樂的播放,讓人有種身臨其境的感覺,甚至忍不住想狠狠購物了呢(誤),大概就是下面這個樣子滴:


嗯,確實很炫,那么我們一步步去分析是如何實現的:

一、實現下雪的 View

首先,最上面一層的全屏雪花極有可能是一個頂層的View,而這個View是通過動態加載去控制顯示的(不更新淘寶也能看到這個效果)。那么我們先得實現雪花效果的 View,人生苦短,拿來就用。打開 gank.io,搜索"雪花":

看樣子第7個庫就是我們想要的了,點進源碼,直接 download 不解釋,記得 star 一個支持作者。那么現在我們的項目中就有一個完整的下雪效果 View 了。

二、實現雪人播放器 View

這個一張雪人圖片+一個按鈕即可實現,就不多解釋了。接下來需要一段圣誕節音頻,直接進行在線音頻播放無疑是節省空間的好方案。『我的滑板鞋』烘托出的寂寞而甜蜜的氛圍無疑是最適合圣誕節的,因此我們得到了『神曲』URL 一枚:
http://cdn.ifancc.com/TomaToDo/bgms/my_hbx.mp3

接下來要找一個小雪人的圖片當作播放器的背景,那么阿姆斯特朗...不對,是這個:

嗯,相當可愛喜慶。那么播放器核心代碼如下:

package com.kot32.christmasview.player;import android.content.Context;import android.media.AudioManager;import android.media.MediaPlayer;import android.util.AttributeSet;import android.view.View;import android.widget.Toast;import com.kot32.christmasview.R;import java.io.IOException;/** * Created by kot32 on 16/12/8. */public class MyPlayer extends View { public MediaPlayer mediaPlayer; public MyPlayer(Context context) {  super(context);  init(); } public MyPlayer(Context context, AttributeSet attrs) {  super(context, attrs);  init(); } private void init() {  setBackgroundResource(R.drawable.pig);  mediaPlayer = new MediaPlayer();  mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);  playUrl("http://172.20.248.106/IXC5b415fcacfc3c439e25a3e74533d2239/TomaToDo/bgms/my_hbx.mp3");  Toast.makeText(getContext(), "開始播放", Toast.LENGTH_SHORT).show();  setOnClickListener(new OnClickListener() {   @Override   public void onClick(View v) {    if (!mediaPlayer.isPlaying()) {     mediaPlayer.start();     Toast.makeText(getContext(), "繼續播放", Toast.LENGTH_SHORT).show();    } else {     mediaPlayer.pause();     Toast.makeText(getContext(), "暫停播放", Toast.LENGTH_SHORT).show();    }   }  }); } public void playUrl(String videoUrl) {  try {   mediaPlayer.reset();   mediaPlayer.setDataSource(videoUrl);   mediaPlayer.prepare();//prepare之后自動播放   mediaPlayer.start();  } catch (IllegalArgumentException e) {   e.printStackTrace();  } catch (IllegalStateException e) {   e.printStackTrace();  } catch (IOException e) {   e.printStackTrace();  } } @Override protected void onDetachedFromWindow() {  super.onDetachedFromWindow();  try {   mediaPlayer.stop();   mediaPlayer.release();  }catch (Exception e){   e.printStackTrace();  } }}

三、動態加載思路

上面基本實現了在本地的雪花以及播放音樂效果,那么在不更新主程序的情況下,如何將這兩個View動態加載到主程序當中去呢?

首先我們明白,Android 的DexClassloader 是擁有加載任意APK 中任意類的能力的,只是有以下限制:

加載出的Activity 由于不在宿主 Manifest 文件中聲明,因此框架無法找到并初始化這個Activity。

加載出的Activity 不具備生命周期,理由同上。

加載出的類的Resource 文件id 會和主程序混淆在一起。

由于我們只是加載View,并不是加載整個Activity,所以前兩個問題并不會遇到,而第三個問題可以想辦法解決掉。

在主程序中我們也要做這三件事:

把能夠裝載View的ViewGroup 的空位留出來

去獲取更新的patch包

把View 從apk包中加載出來之后,放進留好的ViewGroup 中。

這樣一來,不僅是圣誕節,在之后的各種活動上都可以在線去加載活動的View。

四、開始加載

在加載View 之前,首先要意識到這個View 是引用了圖片資源的(小豬圖片),因此我們要解決資源問題:

private void initResource() {  Resources resources = getContext().getResources();  try {   AssetManager newManager = AssetManager.class.newInstance();   Method addAssetPath = newManager.getClass().getMethod("addAssetPath", String.class);   addAssetPath.invoke(newManager, DynamicViewManager.getInstance().getUpdateFileFullPath());   Resources newResources = new Resources(newManager,     resources.getDisplayMetrics(), resources.getConfiguration());   Reflect.onObject(getContext()).set("mResources", newResources);  } catch (Exception e) {   e.printStackTrace();  } }

上面代碼的作用是:把添加了外部更新包路徑的資源管理器賦值給了App原來的資源管理器,也就是說現在可以在宿主中訪問插件資源了。

核心加載代碼如下:

DexClassLoader classLoader = new DexClassLoader(apkFile.getAbsolutePath()     , "dex_out_put_dir"     , null     , getClass().getClassLoader());Class newViewClazz = classLoader.loadClass("view's package name");Constructor con = newViewClazz.getConstructor(Context.class);//first use Activity's Resource lie to Viewif (dynamicView == null) { dynamicView = (View) con.newInstance(getContext());}//Replace the View's mResources and recovery the Activity's avoid disorder of ResourcesReflect.onObject(getContext()).set("mResources", null);getContext().getResources();RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(DisplayUtil.dip2px(getContext(), viewInfo.layoutParams.width),   DisplayUtil.dip2px(getContext(), viewInfo.layoutParams.height));layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);addView(dynamicView, layoutParams);

中間對 mResources 的操作的作用是:將宿主的Activity 的mResources 重置,避免在Activity 中使用資源時和插件沖突。

然而機智的我已經把更新包下載、版本管理、動態加載都封裝好了,所以正確的加載方式是:

引用它:https://github.com/kot32go/dynamic-load-view

然后:

1.宿主聲明:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/tb_bg" > <com.kot32.dynamicloadviewlibrary.core.DynamicViewGroup  android:layout_width="match_parent"  android:layout_height="match_parent"  app:uuid="activity_frame">  <TextView   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:text="原始頁面"   /> </com.kot32.dynamicloadviewlibrary.core.DynamicViewGroup> <com.kot32.dynamicloadviewlibrary.core.DynamicViewGroup  android:layout_width="60dp"  android:layout_height="60dp"  android:layout_alignParentRight="true"  android:layout_centerVertical="true"  app:uuid="activity_player"> </com.kot32.dynamicloadviewlibrary.core.DynamicViewGroup></RelativeLayout>

以上聲明了主界面的布局,當然,在動態加載之前除了原有的"原始頁面"TextView,是不會有任何其他東西的,也就是圣誕節來臨之前的程序。注意:uuid 會和在線包相匹配。

2.打插件包

其實就是把之前包含了我們所寫的兩個View(雪花和雪人)的程序打包成apk。可以不簽名。

3.把插件包放到服務器

在服務器返回的JSON中聲明插件包地址和動態View 的一些參數,這里的演示程序請求地址為:

http://tomatodo.ifancc.com/php/dynamicView.php

返回值為:

{ "version": 54, "downLoadPath": "http://obfgb7oet.bkt.clouddn.com/patch106.apk", "fileName": "patch106.apk", "viewInfo": [ {  "packageName": "com.kot32.testdynamicviewproject.snow.widgets.SnowingView",  "uuid": "activity_frame",  "layoutParams": {  "width": -1,  "height": -1  } }, {  "packageName": "com.kot32.testdynamicviewproject.player.MyPlayer",  "uuid": "activity_player",  "layoutParams": {  "width": -1,  "height": -1  } } ]}

我們聲明了這次在線包的版本,每個View 的包名和布局參數, 以及最重要的 和宿主程序中聲明對齊的uuid。

以上所述是小編給大家介紹的Android中利用動態加載實現手機淘寶的節日特效,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乳源| 秦安县| 申扎县| 清水河县| 闽清县| 黎平县| 甘泉县| 呼和浩特市| 仙桃市| 都匀市| 怀集县| 岳阳县| 高安市| 厦门市| 清水河县| 玛多县| 惠安县| 麦盖提县| 改则县| 寻乌县| 洛川县| 潍坊市| 沐川县| 昌图县| 云浮市| 申扎县| 泸水县| 同江市| 益阳市| 富顺县| 特克斯县| 怀安县| 双鸭山市| 公主岭市| 秭归县| 莱芜市| 大石桥市| 肃南| 渝北区| 阿尔山市| 宣化县|