Android4.0 以后不允许在主线程进行网络连接,否则会出现 android.os.NetworkOnMainThreadException。因此,必须另起一个线程进行网络连接方面的操作。
- package com.lujinhong.irmcdc.dao;
- import java.io.IOException;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import java.util.Scanner;
- public class ResourceDao {
- String returnLine = "hi";
- public String getAllContentByName() {
- Runnable r = new NetWorkHandler();
- Thread thread = new Thread(r);
- thread.start();
- try {
- Thread.sleep(15000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return returnLine;
- }
- private class NetWorkHandler implements Runnable {
- String line = "line";
- Socket socket = null;
- Scanner scanner = null;
- @Override
- public void run() {
- try {
- socket = new Socket("time-A.timefreq.bldrdoc.gov", 13);
- scanner = new Scanner(socket.getInputStream());
- while (scanner.hasNextLine()) {
- line = scanner.nextLine();
- returnLine += line;
- }
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- scanner.close();
- try {
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
1、由于网络连接需要一定时间,为了在主界面上进行网络信息的展现,暂时用sleep()方法简单实现,使主线程等待网络信息读取完成。
- Thread.sleep(5000);
修改以下 问题,使用wai()及nofifyAll处理。
- package com.ljh.irmcdc.dao;
- import java.io.IOException;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import java.util.Scanner;
- public class ResourceDao {
- String returnLine = "";
- public String getAllContentByName() {
- Runnable r = new NetWorkHandler();
- Thread thread = new Thread(r);
- thread.start();
- synchronized (this) {
- try {
- wait(20000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- return returnLine;
- }
- private class NetWorkHandler implements Runnable {
- String line = "line";
- Socket socket = null;
- Scanner scanner = null;
- @Override
- public void run() {
- try {
- // socket = new Socket("time-A.timefreq.bldrdoc.gov", 13);
- socket = new Socket("192.168.136.44", 8179);
- scanner = new Scanner(socket.getInputStream());
- returnLine = "";
- while (scanner.hasNextLine()) {
- line = scanner.nextLine();
- returnLine += line;
- }
- <span style="white-space:pre"> </span>//不要直接使用this,否则nofity的对象不是上面wait所锁定的对象。
- synchronized (ResourceDao.this) {
- ResourceDao.this.notifyAll();
- }
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- scanner.close();
- try {
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
注意:
1、在内部类中引用外部类对象的方法:
- ResourceDao.this.notifyAll();
2、wai()及nofity()必须放在synchronized块里面。
尤其注意在内部类中notify()外部类对象时,不要使用this,而应该是上述所表。
本文介绍如何在Android应用中正确地使用线程进行网络连接操作,避免出现android.os.NetworkOnMainThreadException错误,并通过使用synchronized块和wait/notifyAll方法优化线程同步。
331

被折叠的 条评论
为什么被折叠?



