Android 开发中的多线程编程技术

2013-02-16  来源:本站原创  分类:转贴android  人气:1 

 Java中的线程

  Java的线程类是java.lang.Thread类。当生成一个Thread类的对象之后,一个新的线程就产生了。Java中每个线程都是通过某个特定Thread对象的方法run()来完成其操作的,方法run( )称为线程体。

  下面是构建线程类几种常用的方法:

  public Thread()

  public Thread(Runnable target)

  public Thread(Runnable target, String name)

  public Thread(String name)

  参数target是一个实现Runnable接口的实例,它的作用是实现线程体的run()方法。目标target可为null,表示由本身实例来执行线程。name参数指定线程名字,但没有指定的构造方法,线程的名字是JVM分配的,例如JVM指定为thread-1、thread-2等名字。

  1、Java中的实现线程体方式1

  在Java中有两种方法实现线程体:一是继承线程类Thread,二是实现接口Runnable。下面我们先看看继承线程类Thread方式。

  如果采用第1种方式,它继承线程类Thread并重写其中的方法 run(),在初始化这个类实例的时候,目标target可为null,表示由本实例来执行线程体。由于Java只支持单重继承,用这种方法定义的类不能再继承其他父类,例如代码清单8-1,完整代码请参考chapter8_1工程中chapter8_1代码部分。

  【代码清单8-1】

public class chapter8_1 extends Thread {

boolean isRunning = true;

int timer = 0;

/**
* 线程体代码
*/
@Override
public void run() {
while (isRunning) {
try {
Thread.currentThread().sleep(1000);
timer++;
System.out.println("逝去了 "+timer+" 秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {

chapter8_1 t1 = new chapter8_1();

t1.start();
System.out.println("计时器启动...");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String line = br.readLine();
if (line.equalsIgnoreCase("1")) {
t1.isRunning = false;
/*t1.stop();*/
}
} catch (IOException e) {
e.printStackTrace();
}
}

}

  在main主方法中通过new chapter8_1()创建子线程,并通过t1.start()方法启动子线程,main主方法所在线程为主线程,主线程负责管理其他的子线程。本例进程、主线程和子线程之间的关系如图8-5所示。

  子线程启动之后就开始调用run()方法,run()是一个线程体,我们在子线程中处理事情就是在这里编写代码实现的。本案例中子线程要做的事情就是:休眠1s,计时器加1,再反复执行。Thread.currentThread().sleep(1000)就是休眠1s。

  为了能够停止线程,我们在主线程中增加了一个标识,通过在控制台输入一个字符

  “1”来改变该标识t1.isRunning = false,从而结束这个线程。

 注意:

  事实上线程中有一个stop()方法也可以停止线程,但是由于这种方法会产生线程死锁问题,所以在新版JDK中已经废止了,它的替代解决方法就是增加标识,就是我们在本例中采用的方案。

  很多人觉得线程难理解,主要有两个问题:

  线程休眠,既然线程已经休眠了,程序的运行速度还能提高吗?

  线程体一般都进行死循环,既然线程死循环,程序就应该死掉了,就会没有反应。

  1.关于线程休眠问题

  对线程休眠问题头痛的读者,其实还是在用单线程的思维模式考虑问题,多数情况下我们的PC都是单CPU的,某个时间点只能有一个线程运行。所谓多线程就是多个线程交替执行就好像同时运行似的。因此,休眠当前线程可以交出CPU控制权,让其他的线程有机会运行,多个线程之间只有交替运行效率才是最高的,这就像我们开车过十字路口,只有我等等,让你先过,你再等等让他先过,才能保证最高效率,否则就会造成交通系统崩溃,对线程情况也是一样的。因此,多线程中线程的休眠是程序运行的最有效方式。

  2.关于线程体死循环问题

  在单线程中如果是死循环,程序应就会死掉,没有反应,但是多线程中线程体(run方法)中的死循环,可以保证线程一直运行,如果不循环线程,则运行一次就停止了。在上面的例子中线程体运行死循环,可以保证线程一直运行,每次运行都休眠1s,然后唤醒,再然后把时间信息输出到控制台。所以,线程体死循环是保证子线程一直运行的前提。由于是子线程它不会堵塞主线程,就不会感觉到程序死掉了。但是需要注意的是有时我们确实执行一次线程体,就不需要循环了。

  程序运行后开始启动线程,线程启动后就计算逝去的时间,每过1s将结果输出到控制台。当输入1字符后线程停止,程序终止。

 Java中的实现线程体方式2

  上面介绍继承Thread方式实现线程体,下面介绍另一种方式,这种方式是提供一个实现接口Runnable的类作为一个线程的目标对象,构造线程时有两个带有Runnable target参数的构造方法:

  Thread(Runnable target);

  Thread(Runnable target, String name)。

  其中的target就是线程目标对象了,它是一个实现Runnable的类,在构造Thread类时候把目标对象(实现Runnable的类)传递给这个线程实例,由该目标对象(实现Runnable的类)提供线程体run()方法。这时候实现接口Runnable的类仍然可以继承其他父类。

 请参看代码清单8-2,这是一个Java AWT的窗体应用程序,完整代码请参考chapter8_2工程中chapter8_2_1代码部分。

  【代码清单8-2】

public class chapter8_2_1 extends Frame implements ActionListener, Runnable {

private Label label;
private Button button1;
private Thread clockThread;
private boolean isRunning = false;
private int timer = 0;

public chapter8_2_1() {
button1 = new Button("结束计时");
label = new Label("计时器启动...");
button1.addActionListener(this);
setLayout(new BorderLayout());
add(button1, "North");
add(label, "Center");
setSize(320, 480);
setVisible(true);

clockThread = new Thread(this);
/* 线程体是Clock对象本身,线程名字为"Clock" */
clockThread.start(); /* 启动线程 */
isRunning = true;
}

@Override
public void actionPerformed(ActionEvent event) {
isRunning = false;
}

@Override

public void run() {
while (isRunning) {
try {
Thread.currentThread().sleep(1000);
timer++;
label.setText("逝去了 " + timer + " 秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public static void main(String args[]) {
chapter8_2_1 a = new chapter8_2_1();
}

}

  其中关于Java AWT知识本书就不在这里介绍了,有兴趣的读者可以自己看看相关书籍。在本例中构建AWT窗体的应用程序方式是继承Frame类。采用第1种方式——继承方式实现线程体是不可以的,因为Java是单继承的,这个类不能既继承Frame又继承Thread。应该采用第2种方式——实现Runnable接口方式。Runnable接口也有一个run()方法,它是实现线程体方法,其代码处理与上一节是一样。需要注意的是,在第2种方法中,创建了一个Thread成员变量clockThread,才用构造方法new Thread(this)创建一个线程对象,其中创建线程使用的构造方法是Thread(Runnable target),其中的this就是代表本实例,它是一个实现了Runnable接口的实现类。

  程序运行结果如图8-7所示,屏幕开始加载的时候线程启动开始计算时间,1s更新一次UI,当单击“结束计时”按钮时,停止计时。

 Java中的实现线程体方式3

  实现线程体方式3是实现线程体方式2的变种,本质上还是实现线程体方式2,但是在Android应用开发中经常采用第3种方式。下面我们看第3种方式的计时器代码清单8-3,完整代码请参考chapter8_2工程中 chapter8_2_2代码部分。

  【代码清单8-3】

public class chapter8_2_2 extends Frame implements ActionListener {

private Label label;
private Button button1;
private Thread clockThread;

private boolean isRunning = false;
private int timer = 0;

public chapter8_2_2() {
button1 = new Button("结束计时");
label = new Label("计时器启动...");
button1.addActionListener(this);
setLayout(new BorderLayout());
add(button1, "North");
add(label, "Center");
setSize(320, 480);
setVisible(true);

/* 线程体是Clock对象本身,线程名字为"Clock" */
clockThread = new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
try {
Thread.currentThread().sleep(1000);
timer++;
label.setText("逝去了 " + timer + " 秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});

clockThread.start(); /* 启动线程 */
isRunning = true;
}

@Override
public void actionPerformed(ActionEvent event) {
isRunning = false;
}

public static void main(String args[]) {
chapter8_2_2 a = new chapter8_2_2();
}

}

  与第2种方式比较,我们发现Frame类不再实现Runnable接口了,而是在实例化Thread类的时候,定义了一个实现Runnable接口的匿名内部类:

clockThread = new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
try {
Thread.currentThread().sleep(1000);
timer++;
label.setText("逝去了 " + timer + " 秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});

  有关Java多线程的内容还有很多,例如线程优先级、线程同步等,由于这些内容与本书关系不是很紧密,所以不再介绍了,有关其他的线程知识可以参考Java方面的书籍。接下来介绍一下Android中的线程。

  Android中的线程

  在Android平台中多线程应用很广泛,在UI更新、游戏开发和耗时处理(网络通信等)等方面都需要多线程。Android线程涉及的技术有:Handler;Message;MessageQueue;Looper;HandlerThread。

  Android线程应用中的问题与分析

  为了介绍这些概念,我们把计时器的案例移植到Android系统上,按照在Frame方式修改之后的代码清单8-4,完整代码请参考chapter8_3工程中 chapter8_3代码部分。

  【代码清单8-4】

public class chapter8_3 extends Activity {

private String TAG = "chapter8_3";
private Button btnEnd;
private TextView labelTimer;
private Thread clockThread;
private boolean isRunning = true;
private int timer = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

btnEnd = (Button) findViewById(R.id.btnEnd);
btnEnd.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
isRunning = false;
}
});

labelTimer = (TextView) findViewById(R.id.labelTimer);

/* 线程体是Clock对象本身,线程名字为"Clock" */
clockThread = new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
try {
Thread.currentThread().sleep(1000);
timer++;
labelTimer.setText("逝去了 " + timer + " 秒");
Log.d(TAG, "lost time " + timer);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

});

clockThread.start(); /* 启动线程 */

}
}

  程序打包运行结果出现了异常

系统抛出的异常信息是“Only the original thread that created a view hierarchy can touch its views”,在Android中更新UI处理必须由创建它的线程更新,而不能在其他线程中更新。上面的错误原因就在于此。

  现在分析一下上面的案例,在上面的程序中有两个线程:一个主线程和一个子线程,它们的职责如图8-10所示。

  由于labelTimer是一个UI控件,它是在主线程中创建的,但是它却在子线程中被更新了,更新操作在clockThread线程的run()方法中实现

/* 线程体是Clock对象本身,线程名字为"Clock" */
clockThread = new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
try {
Thread.currentThread().sleep(1000);
timer++;
labelTimer.setText("逝去了 " + timer + " 秒");
Log.d(TAG, "lost time " + timer);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});

  这样的处理违背了Android多线程编程规则,系统会抛出异常“Only the original thread that created a view hierarchy can touch its views”。

  要解决这个问题,就要明确主线程和子线程的职责。主线程的职责是创建、显示和更新UI控件、处理UI事件、启动子线程、停止子线程;子线程的职责是计算逝去的时间和向主线程发出更新UI消息,而不是直接更新UI。

 主线程的职责是显示UI控件、处理UI事件、启动子线程、停止子线程和更新UI,子线程的职责是计算逝去的时间和向主线程发出更新UI消息。但是新的问题又出现了:子线程和主线程如何发送消息、如何通信呢?

  在Android中,线程有两个对象—消息(Message)和消息队列(MessageQueue)可以实现线程间的通信。下面再看看修改之后的代码清单8-5,完整代码请参考chapter8_4工程中chapter8_4代码部分。

  【代码清单8-5】

public class chapter8_4 extends Activity {

private String TAG = "chapter8_3";
private Button btnEnd;
private TextView labelTimer;
private Thread clockThread;
private boolean isRunning = true;
private Handler handler;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

btnEnd = (Button) findViewById(R.id.btnEnd);
btnEnd.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
isRunning = false;
}
});

handler = new Handler() {

@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
labelTimer.setText("逝去了 " + msg.obj + " 秒");
}
}

};

labelTimer = (TextView) findViewById(R.id.labelTimer);

/* 线程体是Clock对象本身,线程名字为"Clock" */
clockThread = new Thread(new Runnable() {
@Override

public void run() {
int timer = 0;
while (isRunning) {
try {
Thread.currentThread().sleep(1000);
timer++;
/* labelTimer.setText("逝去了 " + timer + " 秒"); */
Message msg = new Message();
msg.obj = timer;
msg.what = 0;
handler.sendMessage(msg);
Log.d(TAG, "lost time " + timer);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});

clockThread.start(); /* 启动线程 */

}

  有的时候为了将Android代码变得更加紧凑,把线程的创建和启动编写在一条语句中,如下面chapter8_5的代码片段。代码清单8-6所示,完整代码请参考chapter8_5工程中 chapter8_5代码部分。

  【代码清单8-6】

new Thread() {
@Override
public void run() {
int timer = 0;
while (isRunning) {
ry {
Thread.currentThread().sleep(1000);
timer++;
/ labelTimer.setText("逝去了 " + timer + " 秒");
Message msg = new Message();
msg.obj = timer;
msg.what = 0;
handler.sendMessage(msg);
Log.d(TAG, "lost time " + timer);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}.start();

  chapter8_5代码看起来有些糊涂吧?chapter8_4和chapter8_5创建线程的区别是:chapter8_4采用Thread(Runnable target)构造方法创建一个线程,需要提供一个Runnable接口对象,需要提供的参数是实现了Runnable接口的匿名内部类对象。chapter8_5采用Thread()构造方法创建一个线程,在这里采用了简便的编程方法,直接新建一个Thread类,同时重写run()方法。

  chapter8_5编程方法虽然晦涩难懂,而且违背了Java编程规范,程序结构也比较混乱,但却是Android习惯写法,这主要源于Android对于减少字节码的追求。究竟这两种方式在性能上有多少差别呢?诚实地讲我没有做过测试和求证,在我看来就上面的程序而言它们之间不会有太大差别,由于本书要尽可能遵守Java编程规范和Android的编程习惯,因此本书中两种编程方式都会采用,如果给大家带来不便敬请谅解。

  运行模拟器结果如图8-1所示,加载屏幕后马上开始计时,也可以单击“停止计时”按钮来停止计时。

相关文章
  • Android 开发中的多线程编程技术 2013-02-16

    Java中的线程 Java的线程类是java.lang.Thread类.当生成一个Thread类的对象之后,一个新的线程就产生了.Java中每个线程都是通过某个特定Thread对象的方法run()来完成其操作的,方法run( )称为线程体. 下面是构建线程类几种常用的方法: public Thread() public Thread(Runnable target) public Thread(Runnable target, String name) public Thread(String

  • [转] Android开发手记一 NDK编程实例 2012-07-05

    Android 开发手记一 ---- NDK 编程实例 在 Android 上,应用程序的开发,大部分基于 Java 语言来实现.要使用 c 或是 c++ 的程序或库,就需要使用 NDK来实现. NDK 是 Native Development Kit 的简称.它是一个工具集,集成了 Android 的交叉编译环境,并提供了一套比较方便的 Makefile ,可以帮助开发者快速开发 C 或是 C++ 的动态库,并自动的将 so 和 java 程序打包成 apk ,在Android 上运行. 好,

  • 详解Python中的多线程编程 2014-04-08

    这篇文章主要介绍了详解Python中的多线程编程,Python中的多线程一直是Python学习中的重点和难点,要反复巩固!需要的朋友可以参考下 一.简介 多线程编程技术可以实现代码并行性,优化处理能力,同时功能的更小划分可以使代码的可重用性更好.Python中threading和Queue模块可以用来实现多线程编程. 二.详解 1.线程和进程 进程(有时被称为重量级进程)是程序的一次执行.每个进程都有自己的地址空间.内存.数据栈以及其它记录其运行轨迹的辅助数据.操作系统管理在其上运行的所有进程,

  • Android 开发中使用 SQLite 数据库 2012-01-07

    SQLite 介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PHP, Python)都使用了 SQLite. SQLite 由以下几个组件组成:SQL 编译器.内核.后端以及附件.SQLite 通过利用虚拟机和虚拟数据库引擎(VDBE),使调试.修改和扩展 SQLite 的内核变得更加方便. 图 1. SQLite 内部结构 SQLite 基本上符合 SQL-92

  • Android开发中高效的数据结构 2014-12-13

    android开发中,在java2ee或者android中常用的数据结构有Map,List,Set,但android作为移动平台,有些api(很多都是效率问题)显然不够理想,本着造更好轮子的精神,android团队编写了自己的api用来代替java api SimpleArrayMap<K,V>与ArrayMap<K,V> 实质上ArrayMap继承自SimpleArrayMap,主要是为了实现像HashMap一样的api方法,让习惯使用HashMap的开发者感觉不到差异,本质上是

  • 在Android开发中替换资源图片不起作用的解决方法 2013-10-20

    这篇文章主要介绍了在Android开发中替换资源图片不起作用的解决方法,需要的朋友可以参考下 现象 在android开发中,经常会需要替换res\drawable中的图片,打开res\layout下的文件预览布局页面发现图片已经被替换,但在模拟器或者真实机器上运行时发现该图片并没有被替换,还是使用的是原来的资源图片. 原因 在开发过程中,由于使用模拟器测试了程序,在首次运行后会将res文件夹下的图片资源文件(如drawable-hdpi.drawable-ldpi和drawable-mdpi)拷

  • 在android开发中尽量不要使用中文路径的问题详解 2014-01-12

    本篇文章对在android开发中尽量不要使用中文路径的问题进行了详细的分析介绍.需要的朋友参考下 在开发过程中发现,有些软件对中文路径支持不大好,如果使用Uri.fromFile转换中文路径为uri的时候,有些软件可能会识别不出来导致功能异常,已知的有两个应用:1.腾讯微博的分享功能:2.酷派D530下调用系统摄像头拍照. 如果非要用中文路径,可以采用下面的方式: String path = getCameraTempFilePath(),; //有些系统摄像头对中文路径支持不好,通过Uri.f

  • Android开发中避免应用无响应的方法(Application Not Responding.ANR) 2014-10-27

    这篇文章主要介绍了Android开发中避免应用无响应的方法,即避免弹出Application Not Responding(ANR)对话框,需要的朋友可以参考下 App里发生的最糟糕的事是弹出应用无响应"Application Not Responding" (ANR) 对话框.本课讲的是如何保持应用响应,避免ANR. 什么触发ANR 通常,系统会在应用无法对用户输入响应时显示ANR.比如,如果一个应用在I/O操作上阻塞了(频繁请求网络)UI线程,系统无法处理用户输入事件.或者,在UI

  • 基于linux下C开发中的几点技术经验总结 2014-11-12

    本篇文章是对linux下C开发中的几点技术经验总结进行了详细的分析介绍,需要的朋友参考下 最近一致致力于linux下的C开发,因为老大是某讯出来的.因此,使用的主要技术都是某讯的基本的后台架构思想. 在这段时间,学习到了很多,然后佩服某讯的技术果然很厉害. 因此,自我感觉,从头开发我们这个项目,到现在,跟着我这个大牛级的老大学到了不少东西. 目前在游戏里的公会系统,任务系统,邮件系统,地图,商城,等等很多大大小小的系统,都是由我来负责了. 下面是我最近总结的一点点东西而已,以后还会更多 1.时间

  • android开发中常用的Eclipse快捷键详细整理 2014-11-28

    android开发中常用的Eclipse快捷键详细整理方便查找,需要的朋友可以了解下 Eclipse快捷键-方便查找,呵呵,记性不好 行注释/销注释 Ctrl+/ 块注释/销注释/XML注释 Ctrl+Shift+/ Ctrl+Shift+\ 查找 查找替换 Ctrl+H Ctrl+F 查找下一个/往回找 Ctrl+K Ctrl+Shift+K 跳到某行 Ctrl+L,哈用惯了Editplus,不时会敲下Ctrl+G, 查找当前元素的声明 Ctrl+G 查找当前元素的所有引用 Ctrl+Shif

  • Python中尝试多线程编程的一个简明例子 2014-12-13

    这篇文章主要介绍了Python中尝试多线程编程的一个简明例子,由于GIL的存在,Python中的多线程编程一个是热点和难点问题,需要的朋友可以参考下 综述 多线程是程序设计中的一个重要方面,尤其是在服务器Deamon程序方面.无论何种系统,线程调度的开销都比传统的进程要快得多. Python可以方便地支持多线程.可以快速创建线程.互斥锁.信号量等等元素,支持线程读写同步互斥.美中不足的是,Python的运行在Python 虚拟机上,创建的多线程可能是虚拟的线程,需要由Python虚拟机来轮询调度

  • nodejs中使用多线程编程的方法实例 2014-12-19

    这篇文章主要介绍了nodejs中使用多线程编程的方法实例,本文使用nodejs addon借助c/c++的能力扩展nodejs多线程编程,需要的朋友可以参考下 在以前的博文别说不可能,nodejs中实现sleep中,我向大家介绍了nodejs addon的用法.今天的主题还是addon,继续挖掘c/c++的能力,弥补nodejs的弱点. 我曾多次提到过nodejs的性能问题.其实就语言本身而言,nodejs的性能还是很高的,虽然不及大多部静态语言,但差距也并不大:相对其他动态语言而言,速度优势非

  • Android开发中的9个常见错误和解决方法 2015-01-09

    这篇文章主要介绍了Android开发中的9个常见错误和解决方法,这是Android开发中最常见的9个错误,经过各种各样的整理,以及和热心网友讨论总结而来,需要的朋友可以参考下 经过各种各样的整理,以及和热心网友讨论,终于整理出了九种android开发中最常见的问题和解决方案再次跟大家分享下!!有用的话请顶顶帖子,共同进步.好了不多说了,下面是详解! 1. 如果你的项目的R文件不见的话,可以试下改版本号在保存,R文件不见一般都是布局文本出错导致. 2. 布局文件不可以有大写字母 3. 抛出如下错误

  • Android开发中常用的一些小技巧 2015-02-21

    这篇文章主要介绍了Android开发中常用的一些小技巧,个人总结的一些常用方法和小技巧,需要的朋友可以参考下 Activity.startActivities() 常用于在应用程序中间启动其他的Activity. TextUtils.isEmpty() 简单的工具类,用于检测是否为空 Html.fromHtml() 用于生成一个Html,参数可以是一个字符串.个人认为它不是很快,所以我不怎么经常去用.(我说不经常用它是为了重点突出这句话:请多手动构建 Spannable 来替换 Html.fro

  • 分享Android开发中最有效率最快的循环代码 2015-04-16

    分享Android开发中最有效率最快的循环代码,需要的朋友可以参考下 /* 1 ( 最快 ) */ for (int i = initializer; i >= 0; i--) { ... } /* 2 第二 */ int limit = calculateLoopLimit(); for (int i = 0; i < limit; i++) { ... } /* 3 */ Type[] array = getMyArray(); for (Type obj : array) { ... }

  • Qt中的多线程编程 2010-08-18

    Qt中的多线程编程 级 别: 初级 续欣 ([email protected]), 2004 年 4 月 01 日 Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功能.为了满足用户构造复杂图形界面系统的需求,Qt 提供了丰富的多线程编程支持. Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功能.为了满足用户构造复杂图形界面系统的需求,Qt 提供了丰富的多线程编程支持.从 2.2 版本开始,Qt 主要从下面三个方

  • 浅谈Web开发中的6种技术 2015-04-13

    CSDN博客不再经常更新,更多优质文章请来 粉丝联盟网 FansUnion.cn! (FansUnion) Web开发中的6种技术 1.html 超文本标记语言,即HTML(Hypertext Markup Language),是用于描述网页文档的一种标记语言. 在web开发中,html主要用来构造网站的整体结构. 2.css 级联样式表(Cascading Style Sheet)简称"CSS"它是用来进行网页风格设计的.比如,如果想让链接字未点击时是蓝色的,当鼠标移上去后字变成红色

  • iOS多线程编程技术之NSThread.Cocoa NSOperation.GCD 2014-08-31

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation(iOS多线程编程之NSOperation和NSOperationQueue的使用) 3.GCD全称:Grand Central Dispatch(iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用) 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的. 这篇我们主要介绍和使用NSThread,后

  • Android平台中的安全编程 2015-04-08

    CERT安全编程团队,隶属于卡内基梅隆大学软件工程学院,最近发布了Android平台上Java应用的安全编程指南. CERT在该领域已经有所积累,并且在2013年发布CERT Java安全编程规范,后来出版Java编程指南:可靠安全编程的75条建议一书,该Android指南是对以上工作成果的拓展和延伸.所以,在新版Android编程规范和指南中,一部分是参照已有的Java规范指南,当然也少不了与Android相关,致力于解决移动相关问题的新规则. Lori Flynn是发起CERT Androi

  • 解析Android开发中多点触摸的实现方法 2015-04-03

    多点触摸(MultiTouch),指的是允许计算机用户同时通过多个手指来控制图形界面的一种技术.与多点触摸技术相对应的就是单点触摸,单点触摸的设备已经有很多年了,小尺寸的有触摸式的手机,大尺寸的最常见的就是银行里的ATM机和排队查询机等等 多点触摸技术在实际开发过程中,用的最多的就是放大缩小功能.比如有一些图片浏览器,就可以用多个手指在屏幕上操作,对图片进行放大或者缩小.再比如一些浏览器,也可以通过多点触摸放大或者缩小字体.其实放大缩小也只是多点触摸的实际应用样例之一,有了多点触摸技术,在一定程