webView/多线程

原创 2016年05月31日 21:14:27

网络第一天:webView/多线程

1.webView加载网站

类名:UIWebView

实现方法如下:

(1)创建一个NSURL

NSURL *url = [NSURL URLWithString:@"http://www.tmooc.cn"];

(2)创建一个NSURLRequest类型,就是用于从网络上请求数据的NSURLRequest *request = [NSURLRequest requestWithURL:url];

(3)让我们创建的webView加载请求

[_webView loadRequest:request];

(4)一些常用方法

 //如果网址没有做移动端适配,那么屏幕显示不了全部的, 可以让网页自动缩放来适应

    _webView.scalesPageToFit = YES;


2.webView加载本地文件 

(1)获取本地html文件的地址

  NSString *path = [[NSBundle mainBundle] pathForResource:@"help" ofType:@"html"];

此处的pash是一个字符串,该字符串是一个地址,然后我们需要把该地址转换成URL格式.

(2)根据地址字符串转换成不同样式的文件,然后加载到webView上:


方法1:

  NSURL *url = [NSURL fileURLWithPath:path];

注意此处用的是fileWithPath,而不能用URLWithString,这是获取本地文件跟网络文件的区别!!!!!!!

然后把该url发送给webView

[self.webView loadRequest:[NSURLRequest requestWithURL:url]]


方法2:

    //** 称为二级指针,

    NSError *error = nil;

    //二级指针, 一般用于方法错误的抛出

下面的方法是直接把html文件转换成字符串,一个完整的字符串

    NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];

    if (error) {

        NSLog(@"有错误 %@", error);

    }

    /*baseURL

     比如说一张图片的地址是http://www.baidu.com/111.jpg

     在html中一般写成<image>111.jgp<image>

     其中http://www.baidu.com前缀称为baseURL

     */

然后再把该字符串放到webView上

    //[self.webView loadHTMLString:content baseURL:nil];


方法3:

先转换成二进制数据,然后通过二进制数据加载到webView上

 NSData *data = [NSData dataWithContentsOfFile:path];

    [self.webView loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:nil];


3.多线程

(1)几个概念


进程:(进行中的程序): 每个应用程序在启动起来以后, 就被称为一个进程, 表示他在CPU中占据了一席之地.进程中至少有一个线程, 这个基础的线程被称为主线程.


线程: 用于执行任务的,一个进程可以有多个线程, 通常称为主线程 和 子线程.

规定: 主线程上的任务优先于子线程上的任务执行.每一个线程, 同一时间只能做一件事. 多个任务需要排队执行.


用户可见的,可以感受的操作(UI操作)必须放在主线程中执行, 优先级最高. 非用户可见的操作, 最好不要放到主线程中执行了. 开辟子线程去执行.


关于线程的释放:线程在执行完内部任务以后, 会自动被注销, 释放掉.


管理线程的方式:

1>. pThread : 纯C的, 跨平台. 对于iOS没有优化.

2>.NSThread: 是使用OC对pThread的封装. 早期使用

3>.GCD: C语言, block语法. 对于iOS的多核操作有优化, 对线程处理最专业的方式. 现在的主流

4>.NSOperation: 使用OC语法封装了GCD, 并且额外加了几个功能点.


(2)NSThread

thread(线程)

这种方法需要把执行的操作写到一个方法里面,然后使用使用NSThread提供的方法把自定义的方法放到主线程或者子线程中去.


<1>使用NSThread提供的类别, 来把某个方法的执行放到子线程里

[self performSelectorInBackground:@selector(wasteTime) withObject:nil];

如果想把他放到主线程中,代码如下:

  [self performSelectorOnMainThread:@selector(changeTitle) withObject:nil waitUntilDone:NO];

最后一个参数是表示所选择的方法执行完了之后执行还是不等待直接执行.如果是NO代表不等待,直接执行下方的代码.


<2> 使用NSThread的类工厂方法开线程,开出来的线程是子线程

    [NSThread detachNewThreadSelector:@selector(wasteTime) toTarget:self withObject:nil];


<3>该方法定制性最强,能设置线程的name

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(wasteTime) object:nil];

    //设置线程名称

    thread.name = @"嘻嘻";

    //设置此线程的优先级

    /*优先级排列右 高 -> 低

     NSQualityOfServiceUserInteractive:和用户交互有关系的任务, 例如滚动, 动画, 点击按钮~~

     NSQualityOfServiceUserInitiated: 用户请求的任务, 但是不需要精确处理. 例如用户在消息列表中点击查看某个邮件.

     NSQualityOfServiceUtility: 周期性的用户请求任务, 比如每5分钟刷新一次邮箱. 用户基本不能察觉. 多一次少一次无所谓.

     NSQualityOfServiceBackground: 一些后台优化, 电子邮件App对邮件进行索引以方便搜索.

     NSQualityOfServiceDefault:处于2和3之前的优先级.

     */

    thread.qualityOfService = NSQualityOfServiceDefault;

    

    //启动线程, 需要手动开启

    [thread start];


(3)GCD全称是Grand Central Dispatch,可译为“牛逼的中枢调度器”,GCD是纯C语言的,因此我们在编写GCD相关代码的时候,面对的函数,而不是方法。


一共是四种:异步串行,异步并行,同步串行,同步并行

我的理解是同步异步是决定了执行该任务是否可以开启新的线程,同步的话说明不可以开启新的线程,只能在当前线程下执行,而异步则说明可以开启新的线程。

串行跟并行是修饰队列的,串行队列是任务一个接着一个拍好顺序,等着线程来执行,而并行队列是多个任务并排,等着线程来执行,并行队列只有在异步才有效,因为它需要开辟多个线程来执行。

打个比方,异步就相当于有多扇门的公交车,乘客可以排一条队上车,这好比异步串行。乘客排多条对上车,就好比异步并行。

同步就好比只有一扇门的公交车,乘客只能排一条对上车,这是同步串行,如果排多条道上车,这就是同步并行,但是效果是只能串行上车。


<1>手动创建队列

创建串行队列并添加异步任务:(异步串行)

 dispatch_queue_t queue = dispatch_queue_create("Serial", DISPATCH_QUEUE_SERIAL);

队列创建好以后就可以往队列里添加任务了:(异步串行)

添加异步任务

  dispatch_async(queue, ^{

        for (int i = 0; i < 10; i++) {

            NSLog(@"%d, %@", i , [NSThread currentThread]);

        }

    });

    

    dispatch_async(queue, ^{

        for (int i = 'A'; i <= 'Z'; i++) {

            NSLog(@"%c, %@", i, [NSThread currentThread]);

        }

    });



创建并行队列并添加异步任务:(异步并行)

dispatch_queue_t queue = dispatch_queue_create("Concurrent", DISPATCH_QUEUE_CONCURRENT);

  dispatch_async(queue, ^{

        for (int i = 0; i < 10; i++) {

            NSLog(@"%d, %@", i , [NSThread currentThread]);

        }

    });

    

    dispatch_async(queue, ^{

        for (int i = 'A'; i <= 'Z'; i++) {

            NSLog(@"%c, %@", i, [NSThread currentThread]);

        }

    });


串行队列中添加同步任务(同步串行)

    dispatch_queue_t queue = dispatch_queue_create("Serial", DISPATCH_QUEUE_SERIAL);

    dispatch_sync(queue, ^{

        for (int i = 0; i < 10; i++) {

            NSLog(@"%d, %@", i , [NSThread currentThread]);

        }

    });

    dispatch_sync(queue, ^{

        for (int i = 'A'; i <= 'Z'; i++) {

            NSLog(@"%c, %@", i, [NSThread currentThread]);

        }

    });


创建并行队列并添加同步任务(同步并行)

    dispatch_queue_t queue = dispatch_queue_create("Concurrent", DISPATCH_QUEUE_CONCURRENT);

    //2. 使用同步的方式, 添加打印0~9的方法到并行队列中

    dispatch_sync(queue, ^{

        for (int i = 0; i < 10; i++) {

            NSLog(@"%d, %@", i , [NSThread currentThread]);

        }

    });

    //3. 使用同步的方式, 添加打印A~Z的方法到并行队列中

    dispatch_sync(queue, ^{

        for (int i = 'A'; i <= 'Z'; i++) {

            NSLog(@"%c, %@", i, [NSThread currentThread]);

        }

    });


<2>使用系统自带的队列

你只需要获取它的指针

全局并行队列:

dispatch_queue_t

 queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);

注意这个队列是个并行队列。


主队列:

   dispatch_queue_t mainQueue = dispatch_get_main_queue();

        dispatch_async(mainQueue, ^{

            self.view.backgroundColor = [UIColor greenColor];

        });

这是主线程


常见的锁死:

  dispatch_sync(dispatch_get_main_queue(), ^{

        NSLog(@"------");

    });



【WebView】warnning:所有WebView方法必须在主线程调用(4.0) 所有WebView方法必须在同一线程调用(4.4)

All WebView methods must be called on the UI thread,Future versions of WebView may not support use o...
  • tuhuolong
  • tuhuolong
  • 2014年02月25日 23:11
  • 5849

webview.loadurl应在主线程

webview调用js接口在荣耀畅玩3x(Android 4.2)起作用,在其他4.2以上手机中不起作用的问题 由于我load js接口是在js调用android方法中(带有 @JavascriptI...
  • qianjfsjf
  • qianjfsjf
  • 2016年04月20日 22:54
  • 897

WebView回调所在的线程

WebViewClient和WebChromeClient是在主线程上被回调的 被@android.webkit.JavascriptInterface注解的JS回调是在JavaBridge线程上被...
  • lihuapinghust
  • lihuapinghust
  • 2015年05月14日 11:30
  • 1001

Android WebView学习,创建步骤并附代码(Handler、线程、WebView结合)

WebView允许您为一个Web页面创建一个您自己的窗口。今天,我将创建一个简单的能够包含一个Web页面的Activity。 1.       新建一个项目:HelloWebView. 2.   ...
  • wanzdhan
  • wanzdhan
  • 2011年11月14日 21:26
  • 6578

webview能否多线程WebViewCoreThread;

企图在android上开2个webview来跑2个线程。打印线程ID后发现webview和JAVA UI确实在不同的线程。但是多个webview都在同一个线程WebViewCoreThread。 另...
  • qffj
  • qffj
  • 2013年03月23日 08:59
  • 4003

一次失败的QThread多线程加载Webpage.load()页面的尝试

问题前段时间在用PyQt4写网页加载部分时一开始用的从QWebView.load()(QWebFrame.load()),但由于这样会卡住GUI,于是换了QNetworkAccessManager模块...
  • chroming
  • chroming
  • 2016年07月19日 15:09
  • 1039

Android WebView开发问题及优化汇总

我们在native与网页相结合开发的过程中,难免会遇到关于WebView一些共通的问题。就我目前开发过程中遇到的问题以及最后得到的优化方案都将在这里列举出来。有些是老生常谈,有些则是个人摸索得出解决方...
  • xyz_lmn
  • xyz_lmn
  • 2014年09月24日 11:44
  • 39530

Android WebView的加载超时处理

最近的android项目中有这样一个需求:android中webView加载网页时,加一个链接超时处理,翻阅google官方api,非常奇怪的是Google竟然没有超时的这项设置。随后又Google到...
  • l1028386804
  • l1028386804
  • 2014年01月19日 12:29
  • 7715

Android WebView 开发详解(一)

详细介绍Android WebView开发,介绍WebView开发各个注意事项及其解决方法。
  • typename
  • typename
  • 2014年09月07日 01:17
  • 120167

Android WebView:性能优化不得不说的事

原文链接:http://motalks.cn/2016/09/11/Android-WebView-JavaScript-3/ 版权归作者所有! Mo说:大家通过前两篇文章想必都能顺利的 ...
  • u012210186
  • u012210186
  • 2016年09月21日 14:48
  • 11259
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:webView/多线程
举报原因:
原因补充:

(最多只允许输入30个字)