android同步请求
❶ android原生登录使用webview访问h5 同步登录状态
目前使用的方案:
h5通过js和app交互调用app的token
2.拿到token后使用ajax做异步登录并刷新页面
目前的缺点:
1.会多次刷新页面
2.通过js调用时H5需要做部分改动
优化的方向:
A.APP登陆状态的变化是请求页面,登录后使用webview调用对应域名下的接口实现H5的登录
B.每次请求H5url增加get登陆的信息,例如访问 index.php变成 index.php?a=xxx 通过附加信 息同步登录状态
优化的方案不知道那个更好一点
❷ Android网络请求库【OkHttp4.9.3】基本用法与原理分析
OkHttp是一套处理 HTTP 网络请求的依赖库,由 Square 公司设计研发并开源,目前可以在 java 和 Kotlin 中使用。对于 Android App 来说,OkHttp 现在几乎已经占据了所有的网络请求操作,Retrofit + OkHttp实现网络请求似乎成了一种标配。因此它也是每一个 Android 开发工程师的必备技能,了解其内部实现原理可以更好地进行功能扩展、封装以及优化。
OkHttp的高效性体现在:
第一步:创建OkHttpClient,创建OkHttpClient有两种方式:
OkHttpClient提供了丰富的配置方法,例如添加拦截器、指定连接池、设置请求超时等等。
第二步:创建请求
使用Request.Builder() 构建Request实例
第三步:发起网络请求
OkHttp支持同步和异步两种请求方式
OkHttp的使用方法非常简单,三步操作就可以发起一个简单的同步或异步请求。我们也可以很轻松地对网络请求进行配置,例如添加请求头、设置请求方式、设置请求超时等等,这些配置参数会在源码分析过程中详细介绍。
现在我们已经学会了三步操作发起网络请求,接下来以这三个步骤为切入点,深入到源码中学习OkHttp的实现原理,废话少说马上开车。
OkHttpClient创建方式有两种,我们看看两种方式有什么区别。
第一种直接使用默认构造函数,内部依然是使用建造者模式
第二种使用建造者模式
两种方式最终都是调用构造函数OkHttpClient(builder:Builder),由参数builder负责所有的参数配置工作。
当您创建单个OkHttpClient实例并将其用于所有 HTTP 调用时,OkHttp 性能最佳。 这是因为每个OkHttpClient都拥有自己的连接池和线程池,重用连接和线程可减少延迟并节省内存。 相反,为每个请求创建一个客户端会浪费空闲池上的资源。
Request同样使用建造者模式来创建,这里贴上部分重要源码,很简单就不细说了。
OkHttp发起网络请求分为同步请求和异步请求两种方式,我们只分析异步请求流程,因为只要理解了异步请求过程,基本上也就明白同步请求是怎么一回事了。
RealCall是连接应用层与网络层的桥梁,负责处理连接、请求、响应和数据流。
Dispatcher维护着一套异步任务执行策略,分析策略之前先介绍几个重要概念:
client.dispatcher.enqueue(AsyncCall(responseCallback)) 执行步骤为:
AsyncCall实现了Runnable接口,因此一旦被线程池中的线程处理就会调用它的run()方法:
话休絮烦,我们开始分析拦截器责任链:
责任链执行流程:首先获取当前拦截器interceptor,并且调用interceptor.intercept(next)执行拦截器操作。这里的next表示的是index+1后的责任链对象,拦截器的intercept()方法内部会调用next.proceed(request)方法再次进入到责任链,由于此时index已经加1,所以处理的是下一个拦截器。
如此循环往复,直到处理完责任链上最后一个拦截器为止。
注意除最后一个拦截器CallServerInterceptor不会调用chain.proceed(request)方法之外,其他拦截器都应该至少调用一次chain.proceed(request)方法。
为了验证上面的结论,我们进入到RetryAndFollowUpInterceptor的intercept()方法一探究竟:
可以看到注释1处重新进入责任链处理下一个拦截器。
有兴趣可以自行查看最后一个拦截器CallServerInterceptor源码,此处只给出本人阅读源码后得出的结论:
以上就是拦截器责任链的工作流程,我们再通过流程图仔细感受一下。
分析完拦截器责任链,我们继续分析AsyncCall#run()方法:
我们看到,如果()方法成功获得服务端返回的数据,则调用responseCallback.onResponse(this@RealCall, response)方法完成异步回调;如果服务端数据获取失败(请求异常),则调用responseCallback.onFailure(this@RealCall, canceledException)方法完成异步回调
需要注意的是,responseCallback回调是在子线程中完成的,所以如果想把数据显示到UI上,需要切换回主线程进行UI操作。
OkHttp发起网络请求全过程:
【知识点】OkHttp 原理 8 连问
❸ 如何实现android客户端与服务端数据同步
android客户端不能直接与服务器数据库连接,拿sqlserver来说,安装之后有几个G那么大,android程序是跑在手机上的,想让程序直接访问sqlserver,那手机需要非常大的内存。但是可以通过webservice这样一个桥梁来间接访问SQLServer。
即在服务器运行一个服务端程序,该服务端程序通过接收来自android客户端的指令,对数据库进行操作。客户端与服务端直接的数据传输主要通过http协议发送和接收json数据或者xml数据,服务端接收到客户端的json数据之后,进行json解析,再按一定的逻辑对数据库进行增、删、改、查。客户端的http请求可以通过 HttpClient类实现,在anddroid 4.0之后,客户端的网络请求已经不被允许在主线程中运行,所以题主还需注意另开启一个子线程进行网络请求。
❹ 如何实现 javascript “同步”调用 app 代码
在 App 混合开发中,app 层向 js 层提供接口有两种方式,一种是同步接口,一种一异步接口(不清楚什么是同步的请看这里的讨论)。为了保证 web 流畅,大部分时候,我们应该使用异步接口,但是某些情况下,我们可能更需要同步接口。同步接口的好处在于,首先 js 可以通过返回值得到执行结果;其次,在混合式开发中,app 层导出的某些 api 按照语义就应该是同步的,否则会很奇怪——一个可能在 for 循环中使用的,执行非常快的接口,比如读写某个配置项,设计成异步会很奇怪。
那么如何向 js 层导出同步接口呢?
我们知道,在 Android 框架中,通过 WebView.addJavascriptInterface() 这个函数,可以将 java 接口导出到 js 层,并且这样导出的接口是同步接口。但是在 iOS 的 Cocoa 框架中,想导出同步接口却不容易,究其原因,是因为 UIWebView 和 WKWebView 没有 addJavascriptInterface 这样的功能。同时,Android 这个功能爆出过安全漏洞,那么,我们有没有别的方式实现同步调用呢?我们以 iOS UIWebView 为例提供一种实现,WKWebView 和 Android 也可以参考。
为了找到问题的关键,我们看一下 iOS 中实现 js 调用 app 的通行方法:
首先,自定义 UIWebViewDelegate,在函数 shouldStartLoadWithRequest:navigationType: 中拦截请求。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (BOOL) webView:(UIWebView* _Nonnull)webView
shouldStartLoadWithRequest:(NSURLRequest* _Nonnull)request
navigationType:(UIWebViewNavigationType)navigationType {
if ([request.HTTPMethod compare:@"GET" options:NSCaseInsensitiveSearch] != NSOrderedSame) {
// 不处理非 get 请求
return YES;
}
NSURL* url = request.URL;
if ([url.scheme isEqualToString:@'YourCustomProtocol']) {
return [self onMyRequest:request];
}
return YES;
}
这种做法实质上就是将函数调用命令转化为 url,通过请求的方式通知 app 层,其中 onMyRequest: 是自定义的 request 响应函数。为了发送请求,js 层要建立一个隐藏的 iframe 元素,每次发送请求时修改 iframe 元素的 src 属性,app 即可拦截到相应请求。
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* js 向 native 传递消息
* @method js_sendMessageToNativeAsync
* @memberof JSToNativeIOSPolyfill
* @public
* @param str {String} 消息字符串,由 HybridMessage 转换而来
*/
JSToNativeIOSPolyfill.prototype.js_sendMessageToNativeAsync = function (str) {
if (!this.ifr_) {
this._prepareIfr();
}
this.ifr_.src = 'YourCustomProtocol://__message_send__?msg=' + encodeURIComponent(str); }
当 app 执行完 js 调用的功能,执行结果无法直接返回,为了返回结果,普遍采用回调函数方式——js 层记录一个 callback,app 通过 UIWebView 的 函数调用这个 callback(类似 jsonp 的机制)。
注意,这样封装的接口,天然是异步接口。因为 js_sendMessageToNativeAsync 这个函数会立即返回,不会等到执行结果发回来。
所以,我们要想办法把 js 代码“阻塞”住。
请回忆一下,js 中是用什么方法能把 UI 线程代码“阻塞”住,同时又不跑满 CPU?
1
2
3
4
var async = false;
var url = 'http://.com';
var method = 'GET';<br>var req = new XMLHttpRequest();<br>
req.open(method, url, async);<br>req.send(null);
“同步”ajax(其实没这个词,ajax 内涵异步的意思)可以!在 的响应没返回之前,这段代码会一直阻塞。一般来说同步请求是不允许使用的,有导致 UI 卡顿的风险。但是在这里因为我们并不会真的去远端请求内容,所以不妨一用。
至此实现方式已经比较清楚了,梳理一下思路:
使用同步 XMLHttpRequest 配合特殊构造的 URL 通知 app层。
app 层拦截请求执行功能,将结果作为 Response 返回。
XMLHttpRequest.send() 返回,通过 status 和 responseText 得到结果。
那么,如何拦截请求呢?大家知道,UIWebViewDelegate 是不会拦截 XMLHttpRequest 请求的,但是 iOS 至少给了我们两个位置拦截这类请求——NSURLCache 和 NSURLProtocol。
一、NSURLCache 是 iOS 中用来实现自定义缓存的类,当你创建了自定义的 NSURLCache 子类对象,并将其设置为全局缓存管理器,所有的请求都会先到这里检查有无缓存(如果你没禁掉缓存的话)。我们可以借助这个性质拦截到接口调用请求,执行并返回数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- (NSCachedURLResponse*) cachedResponseForRequest:(NSURLRequest *)request {
if ([request.HTTPMethod compare:@"GET" options:NSCaseInsensitiveSearch] != NSOrderedSame) {
// 只对 get 请求做自定义处理
return [super cachedResponseForRequest:request];
}
NSURL* url = request.URL;
NSString* path = url.path;
NSString* query = url.query;
if (path == nil || query == nil) {
return [super cachedResponseForRequest:request];
}
LOGF(@"url = %@, path = %@, query = %@", url, path, query);
if ([path isEqualToString:@"__env_get__"]) {
// 读环境变量
return [self getEnvValueByURL:url]; //*
} else if ([path isEqualToString:@"__env_set__"]) {
// 写环境变量
return [self setEnvValueByURL:url];
}
return [super cachedResponseForRequest:request];
}
注意注释有 * 号的一行,即是执行 app 接口,返回结果。这里的结果是一个 NSCachedResponse 对象,就不赘述了。
❺ 苹果手机在哪里设置同步呢
首先我们点击打开手机的设置功能
手动将其设置为打开,然后在弹出的对话窗口选择“保留在我的iphone”,这样就成功的将自动同步功能打开了。
❻ 苹果5s同步功能在哪里
iphone5s可以通过以下方法同步:
一、Google账号的联系人同步
1、依次进入“功能表-工具-同步处理-选项-新同步情景模式-编辑。
2、同步情景模式名称处填写:Google Sync
3、进入“应用程序”,选择名片夹,填写如下:
是否同步--选择“是”。
远程数据库处填写:Conetacts。
同步类型:双向
4、进入连接设置
服务器版本:1.2。
服务器识别码:这里很关键“一定是Google,注意第一个字母大写”,否则“系统错误”。
数据承载方式选择:互联网。
接入点:如果用Wi-Fi的话,建议先把Wi-Fi连接好,其它的无所谓。
注:Google Sync支持Wi-Fi,CMNET,CMWAP和3GNET等接入点,在“主机地址”处输入:https://m.google.com/syncml
5、端口:443
6、在“用户名”处输入注册好的Google账号,此处不许输入后缀@gmail.com
7、输入Google账户的密码。
允许同步请求-是;
接受所有同步请求-是;
网络鉴定-否。
8、在“用户名”处输入注册好的Google账号
9、输入Google账户的密码
10、选择“是”,进入下一步,只选中“名片夹”,取消其他项目,选择“选项-同步”即可开始同步。
而Android手机的备份就简单多了,直接登陆常用的Market,一般默认系统是开启账号同步功能的。
二、91手机助导入
使用91手机助手就很简单了。不过导入到苹果手机里面,那就先要先越狱了。
打开91手机助手iphone版,选择资料管理-联系人-导入联系人。这样就可以把备份好的手机名片导入到新手机里了。还可以导出Android手机的名片夹。不过要下载Android版。
三、sim卡中通讯录导入方法
1、sim卡中通讯录的导入方法相信很多网站都曾经教过,但是并没有配图文不够细致。具体方法如下,插入卡后找到iPhone中的设置选项,进入后找到“邮件、通信录、日历”选项。
2、点击进入后再找到通讯录栏目下的“导入sim卡通讯录”即可。
四、QQ同步助手
很多用户的手机导出通讯录后并不能存成csv或Vcard格式,这时需要使用到的软件就是QQ同步助手。
首先在旧手机中下载QQ同步手机助手,以三星手机为例,下载QQ同步手机助手后登陆QQ号,点击“同步”按钮上传至云服务端。
再拿出iPhone,同样下载一个QQ同步手机助手,同样等了刚刚所登陆的QQ,这时会发现自己QQ号内的“云”已经备份了一份通讯录,只要点导入即可。
❼ android 如何关闭NTP网络时间同步
Linux停止ntp服务即可关闭时间同步。
①关闭ntp服务(临时设置重启后自动开启)
service ntpd stop
②设置永久关闭ntp服务(重启后也是关闭的)
chkconfig ntpd off
❽ android网络请求数据是同步还是异步
异步请求,因为UI线程(主线程)不允许有5秒以上的耗时操作.在主线程网络请求会导致阻塞,看起来程序就像假死了一样.所以都是异步请求.
❾ Android-Choreographer 垂直同步 Vsync
view.requestLayout 调用的是 parent.requestLayout,直到 DecorView 最终到 ViewRootImpl.requestLayout 方法。
提示: requestLayout() 跟 invalidate() 区别在于 PFLAG_FORCE_LAYOUT、PFLAG_INVALIDATED,invalidate 不会重新测量布局,只会重新绘制
调用栈:mChoreographer.postCallback(int callbackType, Runnable action, Object token) --> postCallbackDelayed() --> postCallbackDelayedInternal()
至此从调用 requestLayout 到请求 Vsync 信号过程已经结束。
下面看收到 Vsync 信号后,如何处理 mTraversalRunnable 任务。
doTraversal()方法则是 测量、布局、绘制 入口,此处不做分析。
Vsync 垂直同步:
涉及到垂直刷新脉冲、vsync 、gpu 缓冲区 Frame Buffer、Back Buffer 三重缓存,跟 Choreographer
gpu 像素栅格化
垂直同步使得显卡的输出帧数和屏幕的刷新速度保持一致,其中 vsync 用来同步信息,buffer 缓存数据,当 vsync 出现时,cpu 会立即处理下一帧数据写入到缓存中,
之后gpu再渲染数据写在同一个缓存中,当vsync时,下一帧的 buffer 跟当前帧所在的buffer数据交换,当如果之前帧未显示完,是不会进行数据交换的。屏幕扫描下一次的数据显示。
当一个信号来时,假设a b buffer都被占用,此时gpu使用c缓存下一帧的数据,可以有效减少掉帧的几率。
1、view.requestLayout 调用的是 parent.requestLayout ,直到 DecorView 最终到 ViewRootImpl.requestLayout 方法。
2、首先判断正在测量布局,没有则 checkThread 检验当前是否在主线程。在 scheleTraversals 首先中执行同步屏障,其次再将任务 postCallback 给 Choreographer,Choreographer 将任务保存在 mCallbackQueues 中,同时发送 MSG_DO_SCHEDULE_CALLBACK 的同步消息给FrameHandler。FrameHandler 的优先执行 CALLBACK 同步消息调用 doScheleCallback,mCallbackQueues 不为空且 callback 不是延迟执行,调用 scheleFrameLocked 方法请求 Vsync 信号。当运行在 Looper 线程,则立刻调度 vsync,否则,发送消息到UI线程再调度 vsync。其中是通过 FrameDisplayEventReceiver 调度 vysnc。
FrameDisplayEventReceiver 有两个作用,一个是 scheleVsync 请求调度,另一个是接收 vsync 信号回调 onVsync,当接收到 vsync 信号时,调用doFrame 方法,开始渲染下一帧。
doFrame 可以分为三步:一是计算掉帧逻辑,二是记录帧绘制信息,三是处理多种 callback,依次是 input 调用栈,会回调到 DecorView 的 dispatchTouchEvent。
二是 animation 调用栈,执行动画;三是 Traversal 调用栈,即最发送给 Choreographer 的任务
动画如何流畅执行: 调用animation.start时,最终在AnimationHandler会给Choreographer.FrameCallback 回调 doFrame,里面 post了自己。
❿ android 可以监听okhttp的网络请求吗
1、首先 创建 一个mOkHttpClient = new OkHttpClient()对象;
2、构建Request请求对象(根据get和post不同的请求方式分别创建);
3、如果是 post请求还需要 构建 请求参数 Params,RequestBody requestBody = buildFormData(params); builder.post(requestBody).build;;
4、进行网络异步请求 mOkHttpClient.newCall(request).enqueue(new Callback() {} ),如果是同步请求,则改为 Response response = mOkHttpClient.newCall(request).execute()进行 ;
具体实现就不细说了,直接上代码如下:
[html] view plain
public class OkHttpManager {
private static OkHttpManager mOkHttpManager;
private OkHttpClient mOkHttpClient;