Android网络优先级及更改

2023-05-16

Android版本:

Android 4.4.4

涉及内容:

1,网络优先级;
2,网络切换;
3,界面显示。

解决问题:

1,更改网络优先级:让以太网(eth0)优先级高于WiFi(Wlan0);
2,WiFi切换到以太网异常原因及解决。

一、 网络优先级
1、 Android支持的网络类型
Android系统framework层的ConnectivityManager.java文件中 定义了支持的所有网络类型:
frameworks\base\core\java\android\net\ConnectivityManager.java
public static final int TYPE_MOBILE      = 0;
public static final int TYPE_WIFI        = 1;
public static final int TYPE_MOBILE_MMS  = 2;
public static final int TYPE_MOBILE_SUPL = 3;
public static final int TYPE_MOBILE_DUN  = 4;
public static final int TYPE_MOBILE_HIPRI = 5;
public static final int TYPE_WIMAX       = 6;
public static final int TYPE_BLUETOOTH   = 7;
public static final int TYPE_DUMMY       = 8;
public static final int TYPE_ETHERNET    = 9;
public static final int TYPE_MOBILE_FOTA = 10;
public static final int TYPE_MOBILE_IMS  = 11;
public static final int TYPE_MOBILE_CBS  = 12;
public static final int TYPE_WIFI_P2P    = 13;

对于上网,接触的几乎都是 TYPE_WIFITYPE_MOBILE、TYPE_ETHERNET这三种。
这些网络的优先级定义在config.xml文件的networkAttributes数组 中:
frameworks\base\core\res\res\values\config.xml
<!-- This string array should be overridden by the device to present a list of network attributes, based on the hardware -->
<string-array translatable="false" name="networkAttributes">
	<item>"wifi,1,1,1,-1,true"</item>

	<item>"mobile,0,0,0,-1,true"</item>
	<item>"mobile_mms,2,0,2,60000,true"</item>
	<item>"mobile_supl,3,0,2,60000,true"</item>
	<item>"mobile_hipri,5,0,3,60000,true"</item>
	<item>"mobile_fota,10,0,2,60000,true"</item>
	<item>"mobile_ims,11,0,2,60000,true"</item>
	<item>"mobile_cbs,12,0,2,60000,true"</item>
	<item>"wifi_p2p,13,1,0,-1,true"</item>
	<item>"mobile_ia,14,0,2,-1,true"</item>
	<item>"bluetooth,7,7,1,60000,true"</item>
	<item>"eth,9,9,4,60000,true"</item>
</string-array>

注意 networkAttributes数组前的注释!
大意是说,对某种网络支持与否取决与硬件,所以该文件会被源码目录/device/下的config.xml定义的 networkAttributes数组覆盖!!!
也就是说,真正起作用的优先级配置在 源码目录/device/ 下的config.xml中定义。
对于 networkAttributes数组的每一个item:
<item>"wifi,1,1,1,-1,true"</item>
其含义由 NetworkConfig.java描述(一一对应):

frameworks\base\core\java\android\net\NetworkConfig.java
public class NetworkConfig {
    /**
     * Human readable string
     */
    public String name;
    /**
     * Type from ConnectivityManager
     */
    public int type;
    /**
     * the radio number from radio attributes config
     */
    public int radio;
    /**
     * higher number == higher priority when turning off connections
     */
    public int priority;
    /**
     * indicates the boot time dependencyMet setting
     */
    public boolean dependencyMet;
    /**
     * indicates the default restoral timer in seconds
     * if the network is used as a special network feature
     * -1 indicates no restoration of default
     */
    public int restoreTime;
    /**
     * input string from config.xml resource.  Uses the form:
     * [Connection name],[ConnectivityManager connection type],
     * [associated radio-type],[priority],[dependencyMet]
     */
    public NetworkConfig(String init) {
        String fragments[] = init.split(",");
        name = fragments[0].trim().toLowerCase(Locale.ROOT);
        type = Integer.parseInt(fragments[1]);
        radio = Integer.parseInt(fragments[2]);
        priority = Integer.parseInt(fragments[3]);
        restoreTime = Integer.parseInt(fragments[4]);
        dependencyMet = Boolean.parseBoolean(fragments[5]);
    }
}

2、更改以太网优先级高于WiFi

<item>"eth,9,9,0,60000,true"</item>
并设置 Preferred网络为以太网:
frameworks\base\services\java\com\android\server\ConnectivityService.java
mNetworkPreference = getPersistedNetworkPreference();
private int getPersistedNetworkPreference() {
	final ContentResolver cr = mContext.getContentResolver();
	// 设置Preferred网络为TYPE_ETHERNET
	Settings.Global.putInt(cr, Settings.Global.NETWORK_PREFERENCE, ConnectivityManager.TYPE_ETHERNET);
	final int networkPrefSetting = Settings.Global
			.getInt(cr, Settings.Global.NETWORK_PREFERENCE, -1);
	log("networkPrefSetting: " + networkPrefSetting);
	if (networkPrefSetting != -1) {
		return networkPrefSetting;
	}
	return ConnectivityManager.DEFAULT_NETWORK_PREFERENCE;
}

3、网络优先级的读取

frameworks\base\services\java\com\android\server\ConnectivityService.java
public ConnectivityService() {
	if (DBG) log("ConnectivityService starting up");
	boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
	log("wifiOnly=" + wifiOnly);
	String[] naStrings = context.getResources().getStringArray(com.android.internal.R.array.networkAttributes);
	for (String naString : naStrings) {
		try {
			NetworkConfig n = new NetworkConfig(naString);
			if (VDBG) log("naString=" + naString + " config=" + n);
			
			mNetConfigs[n.type] = n;
			mNetworksDefined++;
		}
	}
}

Log如下:



二、 网络切换
现在,优先级:Ethernet > WiFi,在WiFi连接的情况下,点击【使用以太网】按钮进行网络切换:
先响应一个EVENT_CONFIGURATION_CHANGED事件:
frameworks\base\services\java\com\android\server\ConnectivityService.java
case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED: {
	info = (NetworkInfo) msg.obj;
	handleConnectivityChange(info.getType(), false);
	break;
}

对网络是否切换的仲裁在 handleConnect()方法中调用的 isNewNetTypePreferredOverCurrentNetType()方法:

frameworks\base\services\java\com\android\server\ConnectivityService.java
private void handleConnect(NetworkInfo info) {
	final int newNetType = info.getType();
	if (VDBG) {
		log("handleConnect: E newNetType=" + newNetType + " thisIface=" + thisIface
				+ " isFailover" + isFailover);
	}
	// if this is a default net and other default is running
	// kill the one not preferred
	if (mNetConfigs[newNetType].isDefault()) {
		if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != newNetType) {
			if (isNewNetTypePreferredOverCurrentNetType(newNetType)) {
				// tear down the other
				NetworkStateTracker otherNet =mNetTrackers[mActiveDefaultNetwork];
				if (DBG) {
					log("Policy requires " + otherNet.getNetworkInfo().getTypeName() +
						" teardown");
				}
				if (!teardown(otherNet)) {
					loge("Network declined teardown request");
					teardown(thisNet);
					return;
				}
			} else {
				   // don't accept this one
					if (VDBG) {
						log("Not broadcasting CONNECT_ACTION " +
							"to torn down network " + info.getTypeName());
					}
					teardown(thisNet);
					return;
			}
		}
	}
}
private boolean isNewNetTypePreferredOverCurrentNetType(int type) {
	log("type = "+ type);
	log("mNetworkPreference = " + mNetworkPreference);
	log("mActiveDefaultNetwork = " + mActiveDefaultNetwork);
	log("mNetConfigs[mActiveDefaultNetwork].priority = " + mNetConfigs[mActiveDefaultNetwork].priority);
	log("mNetConfigs[type].priority = " + mNetConfigs[type].priority);
	if (((type != mNetworkPreference)
				  && (mNetConfigs[mActiveDefaultNetwork].priority > mNetConfigs[type].priority))
			   || (mNetworkPreference == mActiveDefaultNetwork)) {
		log("return false");
		return false;
	}
	log("return true");
	return true;
}

mNetworkPreference = 9,之前设置的Preferred网络。
mActiveDefaultNetwork = 1,当前使用的网络,即WiFi。
经过 isNewNetTypePreferredOverCurrentNetType()的仲裁,返回true进行网络切换:
Policy requires WIFI teardown

至此, Ethernet当道,WiFi让行。
三、界面显示
在【Settings-->以太网】界面,【使用以太网】选项一直处于连接状态且不可点击,IP地址等信息亦不见;此时进入Shell用ifconfig查看IP,
可知以太网IP等已经获取、且WiFi已经断掉、且ping网络正常。
原因去在Settings部分查找:

packages\apps\settings\src\com\android\settings\ethernet\EthernetSettings.java
public void getEthInfo(int state){	
	if (state == EthernetDataTracker.ETHER_STATE_CONNECTING) {
			mUseEthernet.setEnabled(false);
		mUseEthernet.setSummary(R.string.ethernet_connecting);
			clearIpInfo();
	} else if (state == EthernetDataTracker.ETHER_STATE_DISCONNECTED) {
			mUseEthernet.setEnabled(true);
		mUseEthernet.setSummary(R.string.ethernet_unconnected);
			clearIpInfo();
	} else if (state == EthernetDataTracker.ETHER_STATE_CONNECTED) {
		mUseEthernet.setEnabled(true);
		mUseEthernet.setSummary(R.string.ethernet_connected);
		
		if(isUsingStaticIp()) {
			getEthInfoFromStaticIP();
		} else {
			getEthInfoFromDhcp();
		}
		mEthmac = getEthMac();
	}
}

mUseEthernet不可用原因是以太网一 直处于 ETHER_STATE_CONNECTING 状态,以太网状态来自:
packages\apps\settings\src\com\android\settings\ethernet\EthernetSettings.java
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
	@Override
	public void onReceive(Context context, Intent intent) {
		int state = intent.getIntExtra(EthernetDataTracker.EXTRA_ETHERNET_STATE, 0);
		Log.d(TAG, "BroadcastReceiver: Ethernet current state:" + state);
		getEthInfo(state);
	}
};

广播发送地:
frameworks\base\core\java\android\net\EthernetDataTracker.java
private void runDhcp() {
	Log.d(TAG, "mIface = " + mIface + ", isEthernetEnabled() = " + isEthernetEnabled());
	if(!mIface.isEmpty() && isEthernetEnabled()) {
		registerEthernetContentObserver(); // register here when boot with plugged ethernet
		{
			// send connected msg only when wifi disconnect
			if(!IsWiFiConnected()) {
				sendEthStateChangedBroadcast(ETHER_STATE_CONNECTED);
			} else {
				Log.e(TAG, "WiFiConnected, cannot send ETHER_STATE_CONNECTED MSG");
			}
		}
	}
}
private Boolean IsWiFiConnected() {
	try {
		ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
		boolean isWiFiConnected = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected();
		Log.e(TAG, "isWiFiConnected: " + isWiFiConnected);
		return isWiFiConnected;
	}
}

可知:虽然 WiFi已经被teardown,但IsWiFiConnected()依旧返回true,即WiFi状态没被更新:
frameworks\base\wifi\java\android\net\wifi\WifiStateTracker.java
public boolean teardown() {
	mTeardownRequested.set(true);
	mWifiManager.stopWifi();
	return true;
}

IsWiFiConnected()运行先于WiFi的teardown(),所以在teardown()更改WiFi的状态是无效的。。。既然现在需要Ethernet优先级高于WiFi,直接让IsWiFiConnected()返回false即可。


Android 6.0 Wifi/Ethernet同时开默认动作
先连接WiFi,再开ethernet,WiFi会被系统自动的关掉:状态由connected->saved,log:

03-15 01:18:44.204   556   574 D Tethering: interfaceLinkStateChanged wlan0, true
03-15 01:18:44.205   556   574 D Tethering: interfaceStatusChanged wlan0, true
03-15 01:18:47.585   556   574 D Tethering: interfaceLinkStateChanged eth0, true
03-15 01:18:47.585   556   574 D Tethering: interfaceStatusChanged eth0, true
03-15 01:18:47.591   556   574 D EthernetNetworkFactory: updateInterface: eth0 link up
03-15 01:18:47.596   556  1806 I EthernetNetworkFactory: dhcpThread(eth0): mNetworkInfo=[type: Ethernet[], state: DISCONNECTED/DISCONNECTED, reason: (unspecified), extra: 00:23:9e:03:bd:aa, roaming: false, failover: false, isAvailable: true]
03-15 01:18:47.632  1807  1807 I dhcpcd  : version 5.5.6 starting
03-15 01:18:47.633  1807  1807 E dhcpcd  : get_duid: Read-only file system
03-15 01:18:47.738  1807  1807 I dhcpcd  : eth0: rebinding lease of 192.168.1.64
03-15 01:18:47.895  1807  1807 I dhcpcd  : eth0: acknowledged 192.168.1.64 from 192.168.1.250
03-15 01:18:47.942  1807  1807 I dhcpcd  : eth0: leased 192.168.1.64 for 86400 seconds
03-15 01:18:48.430   556  1806 D ConnectivityService: registerNetworkAgent NetworkAgentInfo{ ni{[type: Ethernet[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: 00:23:9e:03:bd:aa, roaming: false, failover: false, isAvailable: true]}  network{116}  lp{{InterfaceName: eth0 LinkAddresses: [192.168.1.64/22,]  Routes: [192.168.0.0/22 -> 0.0.0.0 eth0,0.0.0.0/0 -> 192.168.1.250 eth0,] DnsAddresses: [192.168.1.250,] Domains:  MTU: 0 TcpBufferSizes: 524288,1048576,3145728,524288,1048576,2097152}}  nc{[ Transports: ETHERNET Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]}  Score{110}  everValidated{false}  lastValidated{false}  created{false} lingering{false} explicitlySelected{false} acceptUnvalidated{false} everCaptivePortalDetected{false} lastCaptivePortalDetected{false} }
03-15 01:18:48.432   556   634 D ConnectivityService: NetworkAgentInfo [Ethernet () - 116] EVENT_NETWORK_INFO_CHANGED, going from null to CONNECTED
03-15 01:18:48.442   556   634 D ConnectivityService: Adding iface eth0 to network 116
03-15 01:18:48.496   556   634 E ConnectivityService: Unexpected mtu value: 0, eth0
03-15 01:18:48.496   556   634 D ConnectivityService: Adding Route [192.168.0.0/22 -> 0.0.0.0 eth0] to network 116
03-15 01:18:48.501   556   634 D ConnectivityService: Adding Route [0.0.0.0/0 -> 192.168.1.250 eth0] to network 116
03-15 01:18:48.506   556   634 D ConnectivityService: Setting Dns servers for network 116 to [/192.168.1.250]
03-15 01:18:48.532   556   634 D ConnectivityService: notifyType IP_CHANGED for NetworkAgentInfo [Ethernet () - 116]
03-15 01:18:48.550   556   634 D ConnectivityService: scheduleUnvalidatedPrompt 116
03-15 01:18:48.550   556   634 D ConnectivityService: updateSignalStrengthThresholds: CONNECT, sending [] to NetworkAgentInfo [Ethernet () - 116]
03-15 01:18:48.551   556   634 D ConnectivityService: rematch for NetworkAgentInfo [Ethernet () - 116]
03-15 01:18:48.551   556   634 D ConnectivityService:    accepting network in place of NetworkAgentInfo [WIFI () - 115]
03-15 01:18:48.552   556   634 D ConnectivityService: notifyType LOSING for NetworkAgentInfo [WIFI () - 115]
03-15 01:18:48.552   556  1797 D NetworkMonitor/NetworkAgentInfo [WIFI () - 115]: Lingering
03-15 01:18:48.559   556   634 D ConnectivityService: Switching to new default network: NetworkAgentInfo{ ni{[type: Ethernet[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: 00:23:9e:03:bd:aa, roaming: false, failover: false, isAvailable: true]}  network{116}  lp{{InterfaceName: eth0 LinkAddresses: [192.168.1.64/22,]  Routes: [192.168.0.0/22 -> 0.0.0.0 eth0,0.0.0.0/0 -> 192.168.1.250 eth0,] DnsAddresses: [192.168.1.250,] Domains:  MTU: 0 TcpBufferSizes: 524288,1048576,3145728,524288,1048576,2097152}}  nc{[ Transports: ETHERNET Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN LinkUpBandwidth>=100000Kbps LinkDnBandwidth>=100000Kbps]}  Score{110}  everValidated{false}  lastValidated{false}  created{true} lingering{false} explicitlySelected{false} acceptUnvalidated{false} everCaptivePortalDetected{false} lastCaptivePortalDetected{false} }
03-15 01:18:48.562   556   634 D ConnectivityService: Setting tx/rx TCP buffers to 524288,1048576,3145728,524288,1048576,2097152
03-15 01:18:48.572   556   634 D CSLegacyTypeTracker: Sending DISCONNECTED broadcast for type 1 NetworkAgentInfo [WIFI () - 115] isDefaultNetwork=true
03-15 01:18:48.572   556   634 D ConnectivityService: sendStickyBroadcast: action=android.net.conn.CONNECTIVITY_CHANGE
03-15 01:18:48.574   556   634 D CSLegacyTypeTracker: Sending CONNECTED broadcast for type 9 NetworkAgentInfo [Ethernet () - 116] isDefaultNetwork=true
03-15 01:18:48.574   556   634 D ConnectivityService: sendStickyBroadcast: action=android.net.conn.CONNECTIVITY_CHANGE
03-15 01:18:48.574   556   556 D Tethering: Tethering got CONNECTIVITY_ACTION
03-15 01:18:48.575   556   577 D Tethering: MasterInitialState.processMessage what=3
03-15 01:18:48.582   556   634 D ConnectivityService: notifyType PRECHECK for NetworkAgentInfo [Ethernet () - 116]
03-15 01:18:48.582   556   556 D Tethering: Tethering got CONNECTIVITY_ACTION
03-15 01:18:48.583   556   577 D Tethering: MasterInitialState.processMessage what=3
03-15 01:18:48.588   556   634 D ConnectivityService: setProvNotificationVisibleIntent null visible=false networkType=MOBILE extraInfo=null highPriority=false
03-15 01:18:48.589   556   634 D ConnectivityService: NetworkAgentInfo [Ethernet () - 116] validation  passed
03-15 01:18:48.589   556   634 D ConnectivityService: notifyType CAP_CHANGED for NetworkAgentInfo [Ethernet () - 116]
03-15 01:18:48.600   556   634 D ConnectivityService: sendStickyBroadcast: action=android.net.conn.INET_CONDITION_ACTION
03-15 01:18:55.216   556   574 D Tethering: interfaceLinkStateChanged wlan0, true
03-15 01:18:55.216   556   574 D Tethering: interfaceStatusChanged wlan0, true
03-15 01:18:56.558   556   634 D ConnectivityService: handlePromptUnvalidated 116
03-15 01:19:13.857   556   632 D WifiStateMachine: starting scan for "360wifi-2"WPA_PSK with 2447
03-15 01:19:14.556   556   574 D Tethering: interfaceLinkStateChanged wlan0, true
03-15 01:19:14.557   556   574 D Tethering: interfaceStatusChanged wlan0, true
03-15 01:19:18.565   556   634 D ConnectivityService: handleLingerComplete for NetworkAgentInfo [WIFI () - 115]
03-15 01:19:18.566   556   632 D WifiNetworkAgent: NetworkAgent: NetworkAgent channel lost
03-15 01:19:18.567   556   634 D ConnectivityService: NetworkAgentInfo [WIFI () - 115] got DISCONNECTED, was satisfying 1
03-15 01:19:18.595   556   632 E WifiConfigStore: handleBadNetworkDisconnectReport (+8) 0 SSID: 360wifi-2, BSSID: f0:79:59:35:f0:5e, MAC: 58:63:56:f6:f2:ff, Supplicant state: COMPLETED, RSSI: -49, Link speed: 72Mbps, Frequency: 2447MHz, Net ID: 0, Metered hint: false, score: 60
03-15 01:19:18.608  1465  1465 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid=f0:79:59:35:f0:5e reason=3 locally_generated=1
03-15 01:19:18.612   556   574 D Tethering: interfaceLinkStateChanged wlan0, false
03-15 01:19:18.612   556   574 D Tethering: interfaceStatusChanged wlan0, false
03-15 01:19:18.613   556   577 D Tethering: InitialState.processMessage what=4
03-15 01:19:18.617   556   577 D Tethering: sendTetherStateChangedBroadcast 0, 0, 0
03-15 01:19:18.618   556   574 D Tethering: interfaceLinkStateChanged wlan0, false
03-15 01:19:18.618   556   574 D Tethering: interfaceStatusChanged wlan0, false
03-15 01:19:18.622   556   634 D ConnectivityService: notifyType LOST for NetworkAgentInfo [WIFI () - 115]
03-15 01:19:18.623   556   632 D WifiStateMachine: WifiStateMachine: Leaving Connected state
03-15 01:19:18.623   556   632 D WifiNative-HAL: stopRssiMonitoring, cmdId 0
03-15 01:19:18.623   556   632 E WifiConfigStore: saveWifiConfigBSSID Setting BSSID for "360wifi-2"WPA_PSK to any
03-15 01:19:18.638   556  1468 D DhcpClient: Clearing IP address
03-15 01:19:18.698   229   551 E Netd    : netlink response contains error (No such file or directory)
03-15 01:19:18.699   229   551 D CommandListener: Clearing all IP addresses on wlan0
03-15 01:19:18.700   229   551 D CommandListener: Setting iface cfg
03-15 01:19:18.703   556  1798 D DhcpClient: Receive thread stopped
03-15 01:19:18.711   556   632 E WifiConfigStore: saveWifiConfigBSSID Setting BSSID for "360wifi-2"WPA_PSK to any
03-15 01:19:18.723   556   632 D WifiStateMachine: Start Disconnecting Watchdog 13
03-15 01:19:18.732   556   632 D WifiNative-HAL: stopRssiMonitoring, cmdId 0
03-15 01:19:18.735   229   551 D CommandListener: Clearing all IP addresses on wlan0
03-15 01:19:18.847   556   632 D WifiConfigStore: Retrieve network priorities after PNO.
03-15 01:19:20.174   556   574 D Tethering: interfaceLinkStateChanged wlan0, false
03-15 01:19:20.174   556   574 D Tethering: interfaceStatusChanged wlan0, false
03-15 01:19:20.260   556   632 E WifiConfigStore:  rewrite network history for "360wifi-2"WPA_PSK

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android网络优先级及更改 的相关文章

  • 新加装的硬盘,装上系统后发现EFI分区没有被创建,还是用旧硬盘的EFI分区

    引发问题 xff1a 如果没有旧硬盘就没法引导系统 xff0c 没法开机 解决办法 xff1a 在新硬盘增加一个EFI分区 目前情况大概就是这个样子 xff1a xff08 本人忘了截图 xff0c 用别人的 xff09 可见 xff0c
  • 信息安全重点知识

    一 信息安全概述 网络空间安全的重要性 xff1a 没有网络安全就没有国家安全信息安全 xff1a 防止数据未授权的访问 xff0c 数据有意和物一的威胁 网络安全是信息安全的子集 信息安全的三要素 xff08 CIA xff09 xff1
  • 线程同步的四种方式

    一 xff0c 什么是线程同步和互斥 同步就是协同步调 xff0c 按预定的先后次序进行运行 如 xff1a 你说完 xff0c 我再说 这里的同步千万不要理解成那个同时进行 xff0c 应是指协同 协助 互相配合 线程同步是指多线程通过特
  • 海天注塑机KEBA系统数据采集

    本文章只针对海天注塑机的KEBA系统 xff0c 因为其他注塑机厂家也用KEBA系统 xff0c 他们的采集方式可能不太一样 xff0c 所以后续有时间我将写其他文章来解释 xff08 默认你已经向海天采购了OPC组件 xff09 一 采集
  • Axure基础:事件和动态面板

    这一篇文章我们主要是将如何做系统左侧的导航 xff0c 并且告诉大家如何动态的切换各个页面 一 事件 1 事件基础 事件的核心就是什么时候做什么事 其中的什么时候可以是如下 xff1a 能做的事情如下 xff1a 2 远程监控云中的事件 监
  • 设备联网调试三板斧

    在实际的工业互联网项目中 xff0c 设备联网所占的比重越来越大 有的一期项目为了简单快速上线 xff0c 让客户直观体会到工业互联网的效果 xff0c 直接会把设备联网放在一期项目的重点 那么在做此类项目时 xff0c 设备联网调试就显得
  • 光立方完全解析

    转载请注明出处 xff1a http blog csdn net ruoyunliufeng article details 37903899 这个4 4 4的三色光立方是我在初学单片机的时候做的一个小项目 很适合给初学单片机和C语言的同学
  • 远程视频监控之应用篇(mjpg-streamer)

    转载请注明出处 xff1a http blog csdn net ruoyunliufeng article details 38515311 这篇文章将主要结合源码介绍mjpg streamer xff0c 使小伙伴们了解视频监控的实现
  • Matplotlib 入门(三):多图合并

    一 多合一显示 1 subplot方法 xff1a 设置行 列和起始点 plt subplot 2 1 1 分成两行一列 xff0c 起始点为1 2 代码 coding utf 8 34 34 34 Created on Sun Sep 2
  • python毫秒级延时

    一 毫秒延时 近期有一个ms级别延时的需求 xff0c 实际测试了一下 xff0c 环境 xff1a win7 64位 xff0c python2 7 13 结果 xff1a 毫秒级别的延时是能够支持的 xff0c 微妙是不支持的 二 de
  • 数据分析之乳腺癌预测

    零 定义问题 1 1 数据介绍 http archive ics uci edu ml machine learning databases breast cancer wisconsin breast cancer wisconsin n
  • 关于mongodb占用内存过大的问题

    一 现象 最近发现自己服务器内存越来越少 xff0c 查了一下原来是部署的mongodb使用内存在线性增加 不查不知道 xff0c 一查吓一跳 xff0c 竟然占用了3G的内存 二 分析 1 内存增加的原因 mongo为了优化他的读写效率
  • 软件开发生命周期-3-每个阶段的输入输出

    记录下一点自己的心得体会 xff0c 分享给大家 xff0c 有不足之处 xff0c 望指教 第一阶段 xff1a 假想阶段 本阶段是整个软件开发的开始阶段 xff0c 输入可以是为了提高工作效率的某个好的想法或者是公司领导为了帮助管理发出
  • make settings时编译报错:dalvik/dx/bin/Android.bp:24:1: module “dx-doc-stubs“ already defined

    FAILED out soong build ninja cd KaTeX parse error Expected 39 EOF 39 got 39 amp 39 at position 51 soong build 34 34 amp
  • Linux下7z压缩解压软件区别

    本文首发于个人博客 xff0c 文章链接为 xff1a https blog d77 xyz archives 4744f068 html 最近需要在 Ubuntu下用 7z 来压缩点东西 xff0c 发现 Ubuntu 默认没有安装 7z
  • FMC接口说明

    FMC介绍 FMC是英文FPGA Mezzanine Card FPGA 夹层卡 的缩写 xff0c 用于FPGA IO和通讯部件之间的连接 实现FPGA具有重配置IO能力的引脚与其他的FMC子卡IO连接 其信号完整性可以保证高达几G bp
  • win10开机为“其他用户”无法登录,及系统登录账户没有管理员权限无法安装软件解决方案

    win10开机为 其他用户 无法登录 xff0c 及系统登录账户没有管理员权限无法安装软件解决方案 开机为 其他用户 无法进入系统无须重装系统 解决方案注意不要漏了管理员权限 xff0c 笔者在给系统加上本地账户之后忘记加管理员权限了 xf
  • java日志之log4j、log4j2、slf4j

    本文从整体视角分析 xff0c 重在帮助初学者了解log4j log4j2之间的关系 以及与slf4j整合时使用的中间jar包 xff1a slf4j log4j12 log4j slf4j impl 1 Log4j log4j核心包只有一
  • Spring框架中的IOC容器及bean管理

    这篇文章讲述的是Spring框架中的IOC容器及bean管理 xff0c 如有错误或者不当之处 xff0c 还望各位大神批评指正 什么是IOC容器 xff1f IOC即反转控制 xff0c 创建对象的权利交给容器来完成 xff0c 而程序要
  • 磁力机航向角计算与补偿

    地理坐标系下该点的磁场强度为 xff08 M 0 xff0c D xff09 xff0c 磁力计测得的三轴磁场强度为 xff08 mx my mz xff09 当我们认为飞机是完全水平放在地上的时候 xff0c 即Z轴和Zb轴是平行的时候

随机推荐

  • Decorators 装饰器

    预备知识 xff1a args的使用方法 xff0c args 用来将参数打包成tuple给函数体调用 例子一 xff1a span class token operator gt gt span span class token oper
  • 一个JAVA程序员成长之路分享

    我搞JAVA也有些日子了 因为我比较贪玩 上进心不那么强 总是逼不得已为了高薪跳槽才去学习 所以也没混成什么大牛 但好在现在也已经成家立业 小日子过的还算滋润 起码顶得住一月近万元的吃喝拉撒玩各种贷款信用卡 不为金钱过于发愁了 我特别感谢当
  • 「Jenkins Pipeline」- 执行 Shell 命令 @20210203

    问题描述 Jenkins Pipeline xff0c 更像 胶水 xff0c 将很多脚本与工具粘合在一起 xff0c 实现自动化任务 xff0c 而它本身并没有提供特定功能 执行 Shell 命令或者脚本是个非常常见的任务 该笔记将记录在
  • 「snap」- ERR - Waiting for automatic snapd restart @20210208

    问题描述 使用 snap 安装 chromium 浏览器时出现如下错误 xff0c 并一直卡住 xff1a 2020 08 21T16 56 10Z INFO Waiting for automatic snapd restart 问题原因
  • 锁屏时间格式不随多用户的时间格式变化而变化?

    背景 xff1a 时间格式有12 24小时制 xff0c 系统设置时间格式之后 xff0c 状态栏和锁屏的时间显示也会相应的发生变化 xff0c 但是现在发现一个问题 xff1a 当我切换到多用户设置时间格式的时候发现 xff0c 状态栏的
  • R语言利用igraph和networkD3包快速入门做出炫酷的社交网络图等几类图。

    原来CDSN编辑器老出问题 xff0c 图片各种显示不好 xff08 老文章依然是原来编辑器 xff09 xff0c 又将本文整理了一遍地址 1 igraph包绘制社交关系图 xff08 也有叫知识图谱的 xff09 绘图的快速入门技巧是三
  • 「Shell」- 判断字符串结尾 @20210209

    下面围绕 判断字符串是否以 txt结尾 展开 转变一下也同样适用于 判断字符串是否以 txt开头 通用的方法 方法一 使用grep命令 bin sh str 61 34 path to foo txt 34 使用if语句 if echo 3
  • 「Firefox」- 在地址栏中,显示二维码 @20210211

    问题描述 在以前某些版本的 Firefox 中 xff0c 地址栏会显示当前地址的二维码 xff0c 再后便消失 xff08 可能功能被取消 xff09 现在 xff08 02 10 2021 xff09 xff0c 我们需要在地址栏中显示
  • 「GNOME 3」- 修改 Topbar 字体(顶部栏字体)、调整默认主题 @20210211

    问题描述 在 GNOME 3 中 xff0c 在进行字体设置时 xff0c 我们发现 Topbar 的字体没有修改 xff0c 因此窗口字体与 Topbar 字体不同 经过搜索 xff0c 我们知道 xff0c Topbar 的字体是主题负
  • 「KVM」- 常见错误及注意事项 @20210223

    启动错误 1 vmport is not available with this QEMU binary 问题描述 xff1a 启动Guest时产生如下错误 xff1a error unsupported configuration vmp
  • 「Jumpserver」- 通过 SSH 连接 Jumpserver 资产 @20210302

    问题描述 在通常情况下 xff0c 我们会通过 Web 界面访问资产 执行命令 xff0c 以进行服务器管理 但是 xff0c 有时候我们也需要通过 SSH 客户端连接服务器 Jumpserver 提供对此的支持 该笔记将记录 xff1a
  • 「Selenium」- 在页面中,点击按钮(或元素) @20210311

    问题描述 该笔记将记录 xff1a 在 Selenium 中 xff0c 如何使用代码点击按钮 xff0c 以及常见问题处理 解决方案 使用 click 点击 通常点击元素使用 click 方法即可 xff1a 选择元素并进行点击 webD
  • 「Linux」- 安装网易云音乐(Neteast Cloud Music) @20210330

    问题描述 我们想在 Ubuntu 20 04 LTS 中安装网易云音乐 xff08 Neteast Cloud Music xff09 xff0c 自然是用来播放音乐 该笔记将记录 xff1a 在 Debian 及衍生版 xff08 比如
  • LaTex | 导出 PNG 图片

    问题描述 我们需要将 LaTeX 文档转换为 PNG 图片 xff08 我们需要使用 LaTeX 的 bytefield 包绘制 字节序列图 xff0c 以在 Zim 中显示 xff09 该笔记将记录 xff1a 如何使用 tex 文件 x
  • Linux:邮箱客户端

    原文地址 xff1a Linux xff1a 邮箱客户端 xff08 永久地址 xff0c 保存网址不迷路 x1f643 xff09 问题描述 我们最开始使用 Thunderbird 邮件客户端 xff0c 但是在 GNOME 3 中当收到
  • Synergy : 多电脑共享鼠标和键盘

    原文地址 xff1a Synergy 多电脑共享鼠标和键盘 xff08 永久地址 xff0c 保存网址不迷路 x1f643 xff09 注意事项 目前 xff08 09 28 2020 xff09 xff0c 建议使用 Barrier xf
  • eslint常用

    0 xff0c 1 xff0c 2分别表示off warning error三个错误级别
  • Kubernetes Objects│Service

    原文地址 xff1a Kubernetes Objects Service xff08 永久地址 xff0c 保存网址不迷路 x1f643 xff09 Service xff0c 服务 xff0c 用于暴露 Pod 以供访问 官方文档及手册
  • draw.io - 安装

    原文地址 xff1a draw io 安装 xff08 永久地址 xff0c 保存网址不迷路 x1f643 xff09 问题描述 我们没有采用自建 draw io 服务 xff0c 而是使用它的客户端 jgraph drawio deskt
  • Android网络优先级及更改

    Android版本 xff1a Android 4 4 4 涉及内容 xff1a 1 xff0c 网络优先级 xff1b 2 xff0c 网络切换 xff1b 3 xff0c 界面显示 解决问题 xff1a 1 xff0c 更改网络优先级