Robotium todolist.test.utils

本文介绍了一个用于控制Android设备网络状态的实用工具类NetworkUtil。该工具提供了开关飞行模式、移动网络及Wi-Fi的功能,并详细展示了如何通过代码实现这些操作。

NetworkUtil

package com.example.todolist.test.utils;

import java.lang.reflect.Method;

import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager;
import android.util.Log;

/**
 * Class is used for working with network (switch on/off Airplane mode, mobile Network, Wifi)
 */
public class NetworkUtil {

    private static final String DISABLE_DATA_CONNECTION_METHOD = "disableDataConnectivity";
    private static final String ENABLE_DATA_CONNECTION_METHOD = "enableDataConnectivity";
    private static final String I_TELEPHONY_METHOD = "getITelephony";
    private static final String TAG = "NetworkSwitcher";

    /**
     * Switch off AirplaneMode, mobile network and wifi
     * 
     * @param context
     * @throws Exception
     */
    public static void setAllPossibleNetworksOn(Context context) throws Exception {
        if (isAirplaneModeOn(context)) {
            boolean success = setAirplaneModeOff(context);
            if (!success) {
                throw new IllegalStateException("AirplaneMode was NOT turned ON");
            }
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        byte numberOfErrors = 0;
        try {
            setNetworkOn(context);
        } catch (Exception e) {
            numberOfErrors++;
        }
        try {
            setWifiOn(context);
        } catch (Exception e) {
            numberOfErrors++;
        }
        if (numberOfErrors == 2) {
            throw new Exception("Wifi and Network are not turned on");
        }
    }

    /**
     * Switch off Wifi network
     * 
     * @param context
     *            - Context
     * @return true if Wifi was switched off successfully
     * @throws SettingNotFoundException
     *             if Wifi settings were not found
     */
    public static boolean setWifiOff(Context context) throws SettingNotFoundException {
        WifiManager wifiMng = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (wifiMng == null) {
            return false;
        }
        if (!wifiMng.isWifiEnabled()) {
            return true;
        }
        Settings.System.putInt(context.getContentResolver(), Settings.Secure.WIFI_ON, 0);
        try {
            wifiMng.setWifiEnabled(false);
            Settings.System.putInt(context.getContentResolver(), Settings.Secure.WIFI_ON, 0);
            return !wifiMng.isWifiEnabled();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Switch On Wifi network
     * 
     * @param context
     *            - Context
     * @return true if Wifi successfully switched on
     * @throws SettingNotFoundException
     *             if Wifi settings were not found
     */
    public static boolean setWifiOn(Context context)  {
        WifiManager wifiMng = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (wifiMng == null) {
            return false;
        }
        if (wifiMng.isWifiEnabled()) {
            return true;
        }
        Settings.System.putInt(context.getContentResolver(), Settings.Secure.WIFI_ON, 1);
        try {
            wifiMng.reassociate();
            wifiMng.reconnect();
            wifiMng.setWifiEnabled(true);
            Settings.System.putInt(context.getContentResolver(), Settings.Secure.WIFI_ON, 1);
            Thread.sleep(5000);
            return wifiMng.isWifiEnabled();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Verify is Wifi network on now
     * 
     * @param context
     *            - Context
     * @return true if Wifi is switched on
     * @throws SettingNotFoundException
     */
    public static boolean isWifiOn(Context context) throws SettingNotFoundException {
        int value = Settings.System.getInt(context.getContentResolver(), Settings.Secure.WIFI_ON);
        return value == 0 ? false : true;
    }

    /**
     * @param context
     *            - Context
     * @return true if Network switched off successfully
     * @throws SettingNotFoundException
     */
    public static boolean setNetworkOff(Context context) throws SettingNotFoundException {
        boolean isEnabled = true;
        if (!isNetworkOn(context)) {
            return true;
        }
        isEnabled = changeNetworkState(context, DISABLE_DATA_CONNECTION_METHOD);
        return !isEnabled;
    }

    /**
     * @param context
     *            - Context
     * @return true if Network switched on successfully
     * @throws SettingNotFoundException
     */
    public static boolean setNetworkOn(Context context) throws SettingNotFoundException {
        boolean isEnabled = false;
        if (isNetworkOn(context)) {
            return true;
        }
        isEnabled = changeNetworkState(context, ENABLE_DATA_CONNECTION_METHOD);
        return isEnabled;
    }

    /**
     * @param context
     *            - Context
     * @return true if it is mobile network connection
     */
    public static boolean isNetworkOn(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        return telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED ? true : false;
    }

    /**
     * 
     * @param context
     * @return true if AirplaneMode is switched successfully
     * @throws SettingNotFoundException
     */
    public static boolean setAirplaneModeOn(Context context) throws SettingNotFoundException {
        if (isAirplaneModeOn(context)) {
            return true;
        }
        boolean success = Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 1);
        if (!success) {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        intent.putExtra("state", true);
        context.sendOrderedBroadcast(intent, null);
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
        }
        return success;
    }

    /**
     * @param context
     * @return true if Airplane mode is on
     * @throws SettingNotFoundException
     */
    public static boolean isAirplaneModeOn(Context context) throws SettingNotFoundException {
        int value = Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON);
        return value == 0 ? false : true;
    }

    /**
     * 
     * @param context
     * @return true if airplane mode is switched successfully
     * @throws SettingNotFoundException
     */
    public static boolean setAirplaneModeOff(Context context) throws SettingNotFoundException {
        if (!isAirplaneModeOn(context)) {
            return true;
        }
        boolean success = Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0);
        if (!success) {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        intent.putExtra("state", false);
        context.sendOrderedBroadcast(intent, null);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
        }
        return success;
    }

    private static boolean changeNetworkState(Context context, String method) throws SettingNotFoundException {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        try {
            Method dataConnSwitchmethod = null;
            Class<?> telephonyManagerClass;
            Object ITelephonyStub;
            Class<?> ITelephonyClass;

            telephonyManagerClass = Class.forName(telephonyManager.getClass().getName());
            Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod(I_TELEPHONY_METHOD);
            getITelephonyMethod.setAccessible(true);
            ITelephonyStub = getITelephonyMethod.invoke(telephonyManager);
            ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName());
            Log.i(TAG, "changeNetworkState(): " + "ITelephonyStub = " + ITelephonyStub.toString());
            dataConnSwitchmethod = ITelephonyClass.getDeclaredMethod(method);
            Log.i(TAG, "changeNetworkState(): " + "ITelephonyClass = " + ITelephonyClass.getName());
            Log.i(TAG, "changeNetworkState(): " + "dataConnSwitchmethod = " + dataConnSwitchmethod.getName());
            dataConnSwitchmethod.setAccessible(true);
            dataConnSwitchmethod.invoke(ITelephonyStub);
            Thread.sleep(5000);
        } catch (Exception e) {
            Log.i(TAG, "changeNetworkState(): Exception: " + e);
            if (method == DISABLE_DATA_CONNECTION_METHOD) {
                setAirplaneModeOn(context);
            }
        }
        return telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED;
    }

    /**
     * Switch on all types of connection
     * 
     * @param context
     */
    public static void setAirplaneModeOffAndNetworkOn(Context context) {
        try {
            if (isAirplaneModeOn(context)) {
                setAirplaneModeOff(context);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    Log.e("[TestRC]", "setAirplaneModeOffAndNetworkOn() : " + e);
                }
            }
        } catch (Exception e) {
            // do nothing
        }
        try {
            setNetworkOn(context);
        } catch (Exception e) {
            // do nothing
        }
        try {
            setWifiOn(context);
        } catch (Exception e) {
            // do nothing
        	e.printStackTrace();
        }
    }

    /**
     * Switched Off all types of connection
     * 
     * @param context
     * @throws NetworkSwitchException
     * @throws SettingNotFoundException
     */
    public static void setAllPossibleNetworksOff(Context context) throws SettingNotFoundException {
        setWifiOff(context);
        try {
            waitForWifiOff(context);
        } catch (Exception e1) {
            Log.e(TAG, e1.getMessage());
        
        setNetworkOff(context);
        try {
            Thread.sleep(6000);
        } catch (Exception e) {
            // ignore
        }
        }
    }

    private static void waitForWifiOff(Context context) throws Exception {
        boolean isWifiOff = false;
        long startTime = System.currentTimeMillis();
        do {
            Thread.sleep(500);
            isWifiOff = !isWifiOn(context);
        } while (!isWifiOff && (System.currentTimeMillis() - startTime < 10000));
        if (!isWifiOff) {
            throw new Exception("Wifi is not turned off");
        }
    }

    public static void waitForWifiOrNetworkOn(Context context) throws Exception {
        boolean isWifiOrNetworkOn = false;
        long startTime = System.currentTimeMillis();
        do {
            Thread.sleep(500);
            isWifiOrNetworkOn = isWifiOn(context) || isNetworkOn(context);
        } while (!isWifiOrNetworkOn
                && (System.currentTimeMillis() - startTime < 10000));
        if (!isWifiOrNetworkOn) {
            throw new Exception("Wifi and Network is not turned on");
        }
    }

}

Util

package com.example.todolist.test.utils;

import android.app.Instrumentation;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.content.Context;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.test.InstrumentationTestCase;
import android.util.Log;

public class Util {
	
	/**
	 * 唤醒设备的方法
	 * @param owner
	 * @return
	 */
	public static WakeLock wakeScreen(InstrumentationTestCase owner) {
		PowerManager pm = (PowerManager) owner.getInstrumentation()
				.getTargetContext().getSystemService(Context.POWER_SERVICE);
		WakeLock wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
				| PowerManager.FULL_WAKE_LOCK
				| PowerManager.ACQUIRE_CAUSES_WAKEUP, owner.getClass()
				.getSimpleName());
		wakeLock.acquire();
		return wakeLock;
	}

	/**
	 * 解锁的方法
	 * @param instr
	 */
	public static void unlock(Instrumentation instr) {
		try {
			Context targetContext = instr.getTargetContext();
			KeyguardManager keyGuardManager = (KeyguardManager) targetContext
					.getSystemService(Context.KEYGUARD_SERVICE);
			KeyguardLock mLock = keyGuardManager.newKeyguardLock("");
			mLock.disableKeyguard();
		} catch (Throwable e) {
			Log.e("TEST", "unlock failed:", e);
		}
	}
}

 

转载于:https://my.oschina.net/children009/blog/759920

<think>好的,我现在需要解决用户的问题:在updateDate()方法中,拼接后的todolist不能实时更新到页面上。用户提供的代码是Vue或类似框架中的方法,因为使用了this.todolist这样的数据属性,并且可能涉及到响应式更新的问题。 首先,我应该想到Vue的响应式原理。Vue通过劫持数据对象的getter和setter来实现响应式,当数据变化时,视图会自动更新。但有些情况下,直接修改数组或对象可能无法触发视图更新,比如通过索引修改数组元素,或者修改对象属性时没有使用Vue.set方法。 用户代码中,当this.todolist的长度为1时,执行push方法添加新对象,这通常是可以触发响应式更新的,因为push是变异方法。但是当长度不为1时,代码直接修改了数组最后一个元素的content和end属性。这里可能存在两个问题: 1. 直接通过索引修改数组元素,比如this.todolist[this.todolist.length-1],如果这个元素是对象,修改其属性应该能触发更新,因为Vue对对象属性的变化是能检测到的,只要属性是在data中初始化的。但如果这个属性是后来添加的,可能需要使用Vue.set。 2.可能用户没有正确使用Vue的响应式方法,比如在修改数组或对象时,没有确保Vue能够检测到变化。例如,如果直接通过索引修改数组元素,Vue可能无法检测到,但如果是修改对象属性,应该可以,除非属性不是响应式的。 此外,用户提到拼接后的数据不能实时更新,可能的原因还有:- 可能在异步操作(如setInterval)中修改数据,而Vue的更新是异步的,可能需要手动强制更新,使用this.$forceUpdate(),但这通常不是推荐做法。 - 检查是否在数据修改后,触发了重新渲染的条件。比如,如果模板中依赖的计算属性或方法没有正确更新,可能导致视图不刷新。 接下来,我需要给出解决方案。可能的解决步骤包括: 1.确保使用数组的变异方法(如push)来修改数组,而不是直接通过索引赋值。在用户代码中,push已经使用了,这部分可能没问题。但后面的修改是直接修改对象的属性,这里需要注意这些属性是否是响应式的。 2. 如果对象的属性是动态添加的,需要使用Vue.set或者Object.assign来确保属性是响应式的。例如,如果end或content属性是在运行时添加的,直接赋值可能导致无法触发更新。 3. 检查是否有其他原因导致视图不更新,比如在循环中使用索引作为key,导致Vue无法正确追踪变化。 用户代码中,当todolist长度不为1时,执行: this.todolist[this.todolist.length-1].content += _obj.content; this.todolist[this.todolist.length-1].end =_obj.end;这里假设content和end属性已经存在于todolist的元素中,那么直接赋值应该触发更新。如果这些属性是后来添加的,可能需要使用Vue.set。 可能的解决方案是,使用Vue.set来确保属性被响应式更新。例如: Vue.set(this.todolist[this.todolist.length-1], 'content', this.todolist[this.todolist.length-1].content + _obj.content); Vue.set(this.todolist[this.todolist.length-1], 'end',_obj.end);或者,使用Object.assign替换整个对象,以触发响应式更新: letlastItem = this.todolist[this.todolist.length -1]; this.todolist.splice(this.todolist.length- 1,1, {...lastItem, content:lastItem.content +_obj.content,end: _obj.end });这样通过splice方法替换数组中的元素,可以触发视图更新。 另外,用户可能在setInterval的回调中修改数据,而Vue的响应式系统可能无法自动检测到变化,需要确保在正确的上下文中执行数据修改,或者手动触发更新。总结,解决方案可能是使用Vue.set或替换整个对象来确保响应式更新。同时,检查属性是否是响应式的,或者在修改数组时使用变异方法。</think>根据代码和现象分析,这属于Vue响应式更新问题。当直接修改对象属性或数组元素时,可能出现视图不更新的情况。以下是解决方案: ```javascript updateDate() { console.info(" todolistrec " + JSON.stringify(this.todolist)) if (this.todolist[this.todolist.length-1].end === '1') { clearInterval(this.iid); return; } let _obj = JSON.parse(this.receiverDataStr); if(this.todolist.length === 1){ // 正确做法:使用数组变异方法 this.todolist.push(_obj) }else{ // 正确做法:创建新对象触发响应式更新 const lastIndex = this.todolist.length - 1 this.todolist.splice(lastIndex, 1, { ...this.todolist[lastIndex], content: this.todolist[lastIndex].content + _obj.content, end: _obj.end }) } this.receiverDataStr = "" } ``` 解释说明: 1. 使用数组的`splice`方法替代直接修改数组元素,因为Vue能检测到数组变异方法 2. 通过展开运算符创建新对象,确保触发响应式更新 3. 对于对象属性修改,推荐创建新对象替换原对象而不是直接修改属性 4. 当需要修改数组指定索引的值时,使用`splice(index, 1, newValue)`是Vue推荐的方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值