Android4.0 以后不允许在主线程进行网络连接

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;
				}
				//不要直接使用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,而应该是上述所表。





原文地址:https://www.cnblogs.com/jediael/p/4304198.html