1.关于ping外网问题 2.定时器的使用 3.线程及超时方法 3.线程池
关于ping外网问题 需求:判断外网是否连接。 问题:连接网线安卓设备中,在插上网线但是外网不通处于局域网时,isConnected依然返回true。 解决:需要判断外网是否通 方法:采用pingIP的方法判断外网
1 2 Process process = Runtime.getRuntime().exec("ping -c 3 -w 100 8.8.8.8); //-c 是指ping的次数 3是指ping 3次 ,-w 100 以秒为单位指定超时间隔,是指超时时间为100秒
但是此方法使用一直无效, 在stackoverflow找到解决方法:加/system/bin/ping Process process = Runtime.getRuntime().exec(“/system/bin/ping -c 3 -w 100 www.baidu.com" );
主要方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public static boolean executeCommand() { try { Process mIpAddrProcess = runtime.exec("/system/bin/ping -c 2 -w 100 www.baidu.com"); int mExitValue = mIpAddrProcess.waitFor(); if (mExitValue == 0) { return true; } else { return false; } } catch (InterruptedException ignore) { ignore.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; }
注意要在子线程执行耗时操作
1 exception:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
定时器的使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private Timer mTimer; private TimerTask mTimerTask; //使用: stopTimer(); mTimer = new Timer(); mTimerTask = new TimerTask() { @Override public void run() { if (count >= COUNT_NUM) { stopTimer(); } else { count++; orderCheck(); } } }; //d秒后开始,每p秒执行一次 if (mTimer != null && mTimerTask != null) mTimer.schedule(mTimerTask, d * 1000, p * 1000);
停止方法
1 2 3 4 5 6 7 8 9 10 11 private void stopTimer() { count = 0; if (mTimer != null) { mTimer.cancel(); mTimer = null; } if (mTimerTask != null) { mTimerTask.cancel(); mTimerTask = null; } }
线程及超时方法 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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 private Thread thread, workThread; private class WorkThread extends Thread { @Override public void run() { //处理比较耗时的操作 //final Message msg = new Message();//使用下面方法 final Message msg = mHandler.obtainMessage(); msg.what = MSG_NERWORK_ICON; msg.arg1 = 1; Callable<String> task = new Callable<String>() { @Override public String call() throws Exception { //执行耗时代码 if ( IpUtil.executeCommand()) { msg.arg1 = 1; } else { msg.arg1 = 0; } return "success"; } }; //设置超时时间,指定时间未执行完则中断 ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<String> future = executorService.submit(task); try { //设置超时时间 String rst = future.get(5, TimeUnit.SECONDS); System.out.println(rst); } catch (TimeoutException e) { msg.arg1 = 0; NbLogUtil.d(TAG, "ExecuteCommand Overtime"); } catch (Exception e) { NbLogUtil.d(TAG, "exception:" + e.getMessage()); } finally { executorService.shutdown(); } mHandler.sendMessage(msg);//发送消息更新UI } }
注意:线程未执行完退出时会出现报错 1 2 3 4 5 6 7 8 9 10 @Override public void onDestroy() { super.onDestroy(); mHandler.removeCallbacksAndMessages(null);//未执行完的handler也要关闭 try { workThread.interrupt();//中断线程 } catch (Exception e) { NbLogUtil.d(TAG, "workThread Exception"); } }
创建基本线程池 corePoolSize: 该线程池中核心线程的数量。
注意:线程池中存在核心线程与非核心线程,核心线程一旦创建会一直执行任务或等待任务到来,而非核心线程只在任务队列塞满任务时去执行多出的任务,并且非核心线程在等待一段时间后将会被回收,这个时间作为参数可调配,见下面的keepAliveTime参数。
maximumPoolSize:该线程池中最大线程数量。(区别于corePoolSize)
keepAliveTime:从字面上就可以理解,是非核心线程空闲时要等待下一个任务到来的时间,当任务很多,每个任务执行时间很短的情况下调大该值有助于提高线程利用率。注意:当allowCoreThreadTimeOut属性设为true时,该属性也可用于核心线程。
unit:上面时间属性的单位
workQueue:任务队列,后面详述。
threadFactory:线程工厂,可用于设置线程名字等等,一般无须设置该参数。
1 2 3 4 5 6 7 8 9 10 11 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { ... } final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,5,1,TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(100));
使用 1 2 3 4 5 Runnable runnable = new Runnable() { @Override public void run() { } }; threadPoolExecutor.execute(runnable);