getSize
获取网络图片的宽高prefetchImage
预加载图片到磁盘缓存abortRequest
取消请求任务queryCache
根据uri查询该图片的缓存位置(memory 或者 disk)具体实现分析如下。getSize
input
: 图片的URIoutput
:图片尺寸对象{ “width”:400, "height":300}
getSize
异步获取网络图片的宽高: public void getSize( final String uriString, final Promise promise) { if (uriString == null || uriString.isEmpty()) { promise.reject(ERROR_INVALID_URI, "Cannot get the size of an image for an empty URI"); return; } Uri uri = Uri.parse(uriString); // 根据URI 创建图片请求对象 ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).build(); // 下载图片并decode DataSource<CloseableReference<CloseableImage>> dataSource = Fresco.getImagePipeline().fetchDecodedImage(request, mCallerContext); DataSubscriber<CloseableReference<CloseableImage>> dataSubscriber = new BaseDataSubscriber<CloseableReference<CloseableImage>>() { @Override protected void onNewResultImpl( DataSource<CloseableReference<CloseableImage>> dataSource) { if (!dataSource.isFinished()) { return; } CloseableReference<CloseableImage> ref = dataSource.getResult(); if (ref != null) { try { CloseableImage image = ref.get(); WritableMap sizes = Arguments.createMap(); sizes.putInt("width", image.getWidth()); sizes.putInt("height", image.getHeight()); promise.resolve(sizes); } catch (Exception e) { promise.reject(ERROR_GET_SIZE_FAILURE, e); } finally { CloseableReference.closeSafely(ref); } } else { promise.reject(ERROR_GET_SIZE_FAILURE); } } @Override protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) { promise.reject(ERROR_GET_SIZE_FAILURE, dataSource.getFailureCause()); } }; dataSource.subscribe(dataSubscriber, CallerThreadExecutor.getInstance()); }
prefetchImage
input
:图片的URI,标识请求的IDoutput
:图片是否预加载成功prefetchImage
将图片下载到磁盘缓存中 public void prefetchImage( final String uriString, final int requestId, final Promise promise) { if (uriString == null || uriString.isEmpty()) { promise.reject(ERROR_INVALID_URI, "Cannot prefetch an image for an empty URI"); return; } Uri uri = Uri.parse(uriString); ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).build(); //下载图片到磁盘 DataSource<Void> prefetchSource = Fresco.getImagePipeline().prefetchToDiskCache(request, mCallerContext); DataSubscriber<Void> prefetchSubscriber = new BaseDataSubscriber<Void>() { @Override protected void onNewResultImpl(DataSource<Void> dataSource) { if (!dataSource.isFinished()) { return; } try { removeRequest(requestId); promise.resolve(true); } finally { dataSource.close(); } } @Override protected void onFailureImpl(DataSource<Void> dataSource) { try { removeRequest(requestId); promise.reject(ERROR_PREFETCH_FAILURE, dataSource.getFailureCause()); } finally { dataSource.close(); } } }; registerRequest(requestId, prefetchSource); prefetchSource.subscribe(prefetchSubscriber, CallerThreadExecutor.getInstance()); }
queryCache
input
: 待查询的uri 数组output
: 图片位于缓存的位置对象
{ "https://s.geilicdn.com/CPC/common/201705/header/images/logo-5f5aeedef4.png": "disk", "https://s.geilicdn.com/CPC/loginNew/201706/login/images/topic-bb6756e79d.png": "memory"}
根据uri查询异步图片所在缓存类型:public void queryCache(final ReadableArray uris, final Promise promise) { // perform cache interrogation in async task as disk cache checks are expensive new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { @Override protected void doInBackgroundGuarded(Void... params) { WritableMap result = Arguments.createMap(); ImagePipeline imagePipeline = Fresco.getImagePipeline(); for (int i = 0; i < uris.size(); i++) { String uriString = uris.getString(i); final Uri uri = Uri.parse(uriString); if (imagePipeline.isInBitmapMemoryCache(uri)) { result.putString(uriString, "memory"); } else if (imagePipeline.isInDiskCacheSync(uri)) { result.putString(uriString, "disk"); } } promise.resolve(result); } }.executeOnExecutor(GuardedAsyncTask.THREAD_POOL_EXECUTOR); }
brew install node
。npm install -g weex-toolkit
,并确保版本号大于0.1.0:$ weex --versioninfo 0.3.4至此,准备工作已经到位,我们可以开始编写Weex程序了。
helloweex.we
的文件,并编写以下代码:<template> <div>通过命令行在
<text>Hello Weex</text>
</div></template>
helloweex.we
文件所在的目录下执行如下命令:$ weex helloweex.weinfo Fri Jul 08 2016 14:30:31 GMT+0800 (CST)WebSocket is listening on port 8082 info Fri Jul 08 2016 14:30:31 GMT+0800 (CST)http is listening on port 8081此时,浏览器会打开一个新的标签页展示
helloweex.we
的执行效果:http://127.0.0.1:8081/weex_tmp/h5_render/?hot-reload_controller&page=helloweex.js&loader=xhr
包含着hot reload
字样,所以可以自然联想到当我们在源文件做修改并保存后,该页面会自动刷新展示效果。hot reload
,修改文本的颜色并实时查看效果:<template> <div>
<text >Hello Weex</text>
</div></template><style>
.title { color: red; }</style>
<template> <div>这样一来,当我们点击文本的时候会出现如下效果:
<text onclick="onClickTitle">Hello Weex</text>
</div></template><style>
.title { color: red; }</style><script>
module.exports = {
methods: {
onClickTitle: function (e) { console.log(e);
alert('title clicked.');
}
}
}</script>
ios/sdk
复制到现有的iOS工程目录下,并根据相对路径更新既有工程的podfile,然后执行pod update
将Weex iOS SDK集成进既有的iOS项目中;初始化Weex环境
和渲染Weex实例
这两个小节中,可能是由于代码是从比较大的项目源码中摘录出来的,所以存在一些不必要或没有上下文的代码。WeexDebugViewController
,进行如下布局:weex helloweex.we --qr -h {ip or hostname}
命令来生成二维码,进行扫描演示,不过解析二维码还是为了获取到Weex程序所在位置。WeexDebugViewController
中:- (void)initWeex { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{2.2.3 运行Weex程序的ViewController
[WXAppConfiguration setAppGroup:@"AliApp"];
[WXAppConfiguration setAppName:@"WeexDemo"];
[WXAppConfiguration setAppVersion:@"1.0.0"];
[WXSDKEngine initSDKEnviroment];
[WXLog setLogLevel:WXLogLevelVerbose];
});
}
ShowWeex
按钮时,我们可以根据两个输入框的内容拼接出要运行的Weex程序的位置,然后将其赋值给用来渲染Weex实例的WeexShowcaseViewController
:- (void)showWeex { NSString *str = [NSString stringWithFormat:@"http://%@:8081/%@", self.ipField.text, self.filenameField.text]; WeexShowcaseViewController *vc = [WeexShowcaseViewController new];接着我们来看看
vc.weexUri = [NSURL URLWithString:str];
[self.navigationController pushViewController:vc animated:YES];
}
WeexShowcaseViewController
的源码:#import <WeexSDK/WeexSDK.h>@interface WeexShowcaseViewController ()@property (nonatomic, strong) WXSDKInstance *weexSDK;@end@implementation WeexShowcaseViewController- (void)dealloc { [_weexSDK destroyInstance];2.2.4 运行起来
}
- (void)viewDidLoad {
[super viewDidLoad]; // Do any additional setup after loading the view.
self.weexSDK.viewController = self; self.weexSDK.frame = self.view.frame;
[self.weexSDK renderWithURL:self.weexUri];
__weak typeof(self) weakSelf = self; self.weexSDK.onCreate = ^(UIView *view) {
[weakSelf.view addSubview:view];
}; self.weexSDK.renderFinish = ^(UIView *view) {
;
}; self.weexSDK.onFailed = ^(NSError *error) { NSLog(@"weexSDK onFailed : %@\n", error);
};
}
- (WXSDKInstance *)weexSDK { if (!_weexSDK) {
_weexSDK = [WXSDKInstance new];
} return _weexSDK;
}
helloweex.we
文件所在的目录,将Weex的dev server跑起来:$ weex -s .info Fri Jul 08 2016 15:38:59 GMT+0800 (CST)http is listening on port 8081 info we file in local path . will be transformer to JS bundle然后在Native上填入对应的IP和程序文件名:
please access http://30.9.112.173:8081/
helloweex.we
示例中只有一个文本元素,现在再添加一个图片元素:<template> <div>然后再执行:
<image src="http://image.coolapk.com/apk_logo/2015/0817/257251_1439790718_385.png"></image>
<text onclick="onClickTitle">Hello Weex</text>
</div></template><style>
.title { color: red; }
.thumbnail { width: 100; height: 100; }</style><script>
module.exports = {
methods: {
onClickTitle: function (e) { console.log(e);
alert('title clicked.');
}
}
}</script>
$ weex helloweex.we
来运行查看效果:WXImgLoaderProtocol
#import <WeexSDK/WeexSDK.h>@interface WeexImageDownloader : NSObject <WXImgLoaderProtocol>@end3.2.2 实现协议接口
WXImgLoaderProtocol
协议,并实现该协议定义的接口:#import "WeexImageDownloader.h"#import <SDWebImage/SDWebImageManager.h>@implementation WeexImageDownloader- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame3.2.3 注册Handler
userInfo:(NSDictionary *)options
completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock { return (id<WXImageOperationProtocol>)[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (completedBlock) {
completedBlock(image, error, finished);
}
}];
}@end
[WXSDKEngine registerHandler:[WeexImageDownloader new] withProtocol:@protocol(WXImgLoaderProtocol)];这样一来,再次运行程序就可以看到图片了:
Weex
缩写成WX
,WeexImageLoaderProtocol
缩写成WXImgLoaderProtocol
,不是很好看。WeexButton
,继承自WXComponent
,然后将其注册进Weex SDK:[WXSDKEngine registerComponent:@"weex-button" withClass:[WeexButton class]];这样一来,我们就可以在.we文件中使用这个标签了:
<weex-button title="hello"></weex-button>标签中的属性我们可以在初始化函数中获得:
- (instancetype)initWithRef:(NSString *)ref type:(NSString*)type通过这些属性,我们可以在组件生命周期中修改组件的样式,比如设置按钮的title:
styles:(nullable NSDictionary *)styles
attributes:(nullable NSDictionary *)attributes
events:(nullable NSArray *)events
weexInstance:(WXSDKInstance *)weexInstance {
self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]; if (self) {
_title = [WXConvert NSString:attributes[@"title"]];
} return self;
}
- (void)viewDidLoad { [super viewDidLoad]; self.innerButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; self.innerButton.frame = self.view.bounds;3.3 自定义模块
[self.view addSubview:self.innerButton];
[self.innerButton setTitle:self.title forState:UIControlStateNormal];
[self.innerButton addTarget:self action:@selector(onButtonClick:) forControlEvents:UIControlEventTouchUpInside];
}
@synthesizeweexInstance;WX_EXPORT_METHOD(@selector(call:withParam:callback:))-(void)call:(NSString *)api withParam:(NSDictionary *)param callback:(WXModuleCallback)callback {
注意点如下:WXModuleProtocol
协议;synthesize
)weexInstance
属性;WX_EXPORT_METHOD
来暴露API;WXModuleCallback
进行回调;[WXSDKEngine registerModule:
,就可以在.we文件中使用了:<script> module.exports = {4为Weex做贡献
methods: {
onClickTitle: function (e) { var mymodule = require('@weex-module/mymodule');
mymodule.call('api', {}, function(ret) {
});
}
}
}</script>
上一篇:lcr数字电桥 入门功略_11
下一篇:CCNP是 什么_1
发表评论