您的位置:首页 > 移动开发 > Android开发

weex android 基础与扩展本地图片加载 gif播放自定义module

2017-08-30 17:29 525 查看
本来计划每天写一个,将 weex html部分写完,因为现在很多使用weex的在android 上面有很多基础问题,所以就还是先把 weex android 基础略做一下介绍

分为几个部分

1 android基础

2 weex 项目结构

3 扩展Imageadapter 实现本地图片加载

4 自定义 android 的 gif 播放组件

5 自定义module 获取android 版本号

6 扩展module

效果图先发上来

效果图中对应的分别是

1:text 中读取了android 的当前版本

2:使用image展示本地gif,没有动画效果

3:使用image展示本地图片

4:使用自定义gifview 展示动画



下面这个看gif效果



首先,很多人是因为没有任何android 知识的,希望基于 weex toolist或者 weexpack 去创建weex 项目,很多人会有基于这个的各种各样的问题,其实都是android 很基础的问题,这里就将weex android 上的基础问题都做一个介绍,本人是非常不建议不懂得任何android 的基础去基于weex的工具链去做android 或者ios 的项目,很多人做一半说weex坑实在太多了,weex创建的项目包名怎么改啊,然后都不说那些热更新怎么配置啊等等的略高级的问题了,可能一个稍微复杂的需求就进行不下去了,这些都是android基础实在薄弱。工具链如果很完善的情况下,我们会建议使用工具链,就想vue的脚手架,很成熟完善了,完全没问题,但是weex 得如果用过的会发现问题还是很多,很多地方还是要手动改的,所以花个一周时间把android ios该了解的都了解一下还是很有必要,毕竟你要写的是一个app,而不是一个网页,避免有些原生功能需要你去写,就束手无策了,例如让写个支付啊,或者写个语音什么就完全蒙逼了

第一 :搭建一个 android studio 的开发环境

自行下载安装,不多做介绍

项目基础配置

jdk android 使用的是java语言

android sdk 编译android项目

gradle 打包使用

站桩过程中这几个可以留意一下

第二 :创建一个weex 的android项目

https://github.com/weexteam/article/issues/25

weex项目相当于一个android项目引入了weex依赖,但是也可以不完全使用weex,只是把weex作为里面的某一个功能模块

android 引入jar 包有两种方式

源码依赖:能够快速使用WEEX最新功能,可以根据自己项目的特性进行相关改进。

SDK依赖:WEEX 会在jcenter 定期发布稳定版本。

个人建议不熟悉android的可以采用sdk依赖,这个版本相对稳定,但是新特性会少。源码依赖的话可以去改它的源码,如果水平够了可以尝试

不过如果自己实在集成困难,可以参考官方已经集成好的例子

官方参考栗子

https://github.com/xkli/WXSample

下载项目,使用android studio导入,后编译

第三 :认识 weex 的android项目

weex 的android 项目其实就是一个普通的android项目引入了 weex 的sdk aar,就可以在这个项目里面使用weex的功能





android项目的基础项目结构



android 的清单文件介绍



gradle配置

第四 :weex android项目介绍



依赖weex的android源码介绍

weex gradle脚本简单注释版本

apply plugin: 'com.android.application'
android {
compileSdkVersion 23 // 编译sdk版本
buildToolsVersion '25.0.0' // 编译工具版本

defaultConfig {
applicationId "com.weex.sample" // 应用id 和包名有区别,同样的包名可以有很多不同的applicationid
minSdkVersion 14  //最小兼容sdk版本号
targetSdkVersion 23 // 目标sdk版本号 23是一个分水岭,决定是否需要动态请求权限
versionCode 1  // 应用版本号,每发布一个新版本需要提升一个版本号
versionName "1.0"// 应用版本号对应的版本名字

/**
* 这个是weex 的东西 必须加,否则64位手机无法加载so文件
*/
ndk {
abiFilters "x86"
abiFilters "armeabi"
}
}
buildTypes {
release {
//代码编译混淆引入
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

// 依赖包 ,和 node 里面的dependeceies 很像,就是依赖的第三方库,一个是js的,一个是java的
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.alibaba:fastjson:1.1.45'

compile 'com.taobao.android:weex_sdk:0.10.0@aar'// 这里添加了 weex 相关依赖
compile 'com.android.support:design:23.4.0'
testCompile 'junit:junit:4.12'

compile 'com.squareup.picasso:picasso:2.5.2'
}


第五 :weex 实现适配器adapter

这个专门拿出来说一下,是因为这块的扩展可以实现我们直接去获取本地的资源图片,这样的话,就可以让我们的代码少请求很多资源,就能快很多

例如,我在我的vue里面访问图片是这么写的

<image src="../../assets/account.png" style="width:268px;height:200px;"></image>


那么我们在adapter里面就能拿到这个路径,然后我们把这个路径转化成我们本地图片的assets文件的路径并读取出来就ok了(weex里面一个注意点,图片必须标注宽高,否则不能显示)

public class ImageAdapter implements IWXImgLoaderAdapter {
/***
*参数介绍  url 就是我们上面 image 传过来的src  ImageView就是我们图片显示的控件,这个是weex做的事情,我们就暂时只要知道是这么回事就好了,WXImageQuality是显示图片的质量,是否需要压缩。 WXImageStrategy是我们加载图片的一系列动作过程
*/
@Override
public void setImage(final String url, final ImageView view, WXImageQuality quality, final WXImageStrategy strategy) {

//android 除去少数个把控件 修改UI一定要在UI线程,否则会出现异常
WXSDKManager.getInstance().postOnUiThread(new Runnable() {
@Override
public void run() {
if(view==null||view.getLayoutParams()==null){
return;
}
if (TextUtils.isEmpty(url)) {
view.setImageBitmap(null);
return;
}
//上面这两个异常判断就略过了,简单来说就是你定义了image却没有给宽高,或者没有给src,那么我们就直接return了

String temp = url;
//如果我的本地图片是 src="../../assets/account.png" 这个形式的,所以url只要是 /../../assets 这样打头的说明是去读取本地文件的
if (url.startsWith("/../../assets")) {
//我们把路径替换为我们android项目中的assets文件路径,android访问assets里面的文件只需要 直接WXEnvironment.getApplication().getAssets().open("文件名");就可以了

temp = temp.replace("/../../assets/","");
Log.d("setimage", "temp = " + temp);
try {
InputStream is = WXEnvironment.getApplication().getAssets().open(temp);
view.setImageBitmap(BitmapFactory.decodeStream(is));
}catch (Exception e){
e.printStackTrace();
}
}else{
//如果不是以上面格式访问的图片,我们就认为是网络图片了,那下面是我们依赖Picasso 简单实现了网络图片加载,这样写会很灵活,譬如我们通常需要下载中显示一个图片,图片下载失败了显示一个err图片等等
if (view.getLayoutParams().width <= 0 || view.getLayoutParams().height <= 0) {
return;
}
Picasso.with(WXEnvironment.getApplication()).load(url)
.placeholder(R.mipmap.icon_stub)//这里是放一个下载中的图片
.error(R.mipmap.em_empty_photo)//这里放一个下载失败的图片
.into(view);

}
}
},0);
}

}


一个简单的图片适配器就写好了

第六 :weex 扩展自定义组件(android显示gif)

这边举个简单栗子扩展一个 android 的gif组件

是weex的 android扩展中的Component扩展

https://weex.apache.org/cn/references/advanced/extend-to-android.html

首先需要一个自定义的android控件,为了不重复的造轮子而占去大量篇幅,毕竟android自定义控件不是我们本篇的重点,我github上拿了一个现成的

https://github.com/koral–/android-gif-drawable

使用这个gif播放控件

这个控件有了,那么我们要写一个能够给weex的vue使用的控件了,下面是重点

package com.weex.sample.extend.compontent;

import android.content.Context;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.dom.WXDomObject;
import com.taobao.weex.ui.component.WXComponent;
import com.taobao.weex.ui.component.WXComponentProp;
import com.taobao.weex.ui.component.WXVContainer;

import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;

/**
* Created by neo
*/
public class GifImage extends WXComponent<GifImageView> {

GifImageView gifview;
Context context;
public GifImage(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, boolean isLazy) {
super(instance, dom, parent, isLazy);
}

@Override
protected GifImageView initComponentHostView(Context context) {
gifview = new GifImageView(context);
this.context = context;
return gifview;
}

@WXComponentProp(name = "src")//该注解,则为weex中调用的方法名
public void setSrc(String src){
try{
GifDrawable gifFromAssets = new GifDrawable( context.getAssets(), src);
gifview.setImageDrawable(gifFromAssets);
}catch (Exception e){
e.printStackTrace();
}
}
}


这样就扩展好一个组件了,不过这样扩展完之后并不能使用,我们需要去注册这个组件,注册可以在activity,也可以在application

package com.weex.sample;

import android.app.Application;
import com.taobao.weex.InitConfig;
import com.taobao.weex.WXSDKEngine;
import com.taobao.weex.common.WXException;
import com.weex.sample.extend.compontent.GifImage;
import com.weex.sample.extend.compontent.RichText;
import com.weex.sample.extend.module.PhoneInfoModule;

/**
* 注意要在Manifest中启用
* 参考manifest,否则会抛出ExceptionInInitializerError
* 要实现ImageAdapter 否则图片不能下载
* gradle 中一定要添加一些依赖,否则初始化会失败。
* compile 'com.android.support:recyclerview-v7:23.1.1'
* compile 'com.android.support:support-v4:23.1.1'
* compile 'com.android.support:appcompat-v7:23.1.1'
* compile 'com.alibaba:fastjson:1.1.45'
*/
public class WXApplication extends Application {

@Override
public void onCreate() {
super.onCreate();
InitConfig config = new InitConfig.Builder().setImgAdapter(new ImageAdapter()).build();
WXSDKEngine.initialize(this, config);
try {
WXSDKEngine.registerModule("poneInfo", PhoneInfoModule.class);
WXSDKEngine.registerComponent("rich", RichText.class, false);
WXSDKEngine.registerComponent("gifimage", GifImage.class, false);//注册我们写的gif动图组件
} catch (WXException e) {
e.printStackTrace();
}
}
}


这样我们就可以在vue里面使用了

<!-- android 的话用自定义标签 -->
<gifimage src="loading.gif" style="width:250px;height:500px;margin-left:250px;" ></gifimage>


这样的代码,我们就能看到我们的gif动图了

第七 : 扩展module

扩展module是什么呢,weex 是一个基于MVVM的框架,组件是view层 ,那么简单理解一下module是一些提供数据或者方法给vue去调用的一个东西,譬如我要获取一个地理位置信息等等,那么这里我们就去简单写一个获取应用版本号的方法,也正好知道一下我们android的版本号是怎么一回事

写一个module

package com.weex.sample.extend.module;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import com.taobao.weex.annotation.JSMethod;
import com.taobao.weex.bridge.JSCallback;
import com.taobao.weex.common.WXModule;
import java.util.HashMap;
import java.util.Map;

/**
* Created by neo
*/

public class PhoneInfoModule extends WXModule {

/***
* 获取版本号
* @return
*/
@JSMethod(uiThread = false)
public void getVersionName(String value,JSCallback callback)
{
String version="";
try{
// 获取packagemanager的实例
PackageManager packageManager =mWXSDKInstance.getContext().getPackageManager();
// getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(mWXSDKInstance.getContext().getPackageName(),0);
version = packInfo.versionName;
}catch (Exception e){
e.printStackTrace();
}
callback.invoke(version);
}
}


注册module 参考commpontent 在application中的注册了,那里面已经写了这个类的注册了

WXSDKEngine.registerModule("poneInfo", PhoneInfoModule.class);


然后我们再vue中去使用这个方法

<template>
<div style="margin:20px;">
<text>版本号为{{version}}</text>
</div>
</template>
<style scoped>

</style>
<script>
export default {
data(){
return {
version:'0.0.0'
}
},
created(){
const _self = this
//本来是不需要传递一个 参数给 getVersionName 方法的,由于ios有个蛋疼的问题,如果不传参数就拿不到数据,所以习惯性的给一个空过去
weex.requireModule('poneInfo').getVersionName('',function(info){
//info 为版本号信息
_self.version = info
});
}
}
</script>


这就完成了

下载地址

vue代码很简单,就不上传了,这里贴一下主要代码

<template>
<div style="margin:20px;">
<text>版本号为{{version}}</text>
<!-- 否则用 image-->
<image src="../../assets/loading.gif" style="width:268px;height:200px;margin-top:50px;"></image>
<image src="../../assets/account.png" style="width:268px;height:200px;margin-top:50px;"></image>
<gifimage src="loading.gif" style="width:268px;height:200px;margin-top:50px;" ></gifimage>
</div>
</template>
<style scoped>

</style>
<script>
export default {
data(){
return {
version:'0.0.0'
}
},
created(){
const _self = this
//本来是不需要传递一个 参数给 getVersionName 方法的,由于ios有个蛋疼的问题,如果不传参数就拿不到数据,所以习惯性的给一个空过去
weex.requireModule('poneInfo').getVersionName('',function(info){
//info 为版本号信息
_self.version = info
});
}
}
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  weex android