Android 8 Wifi 初始化过程
记录一下wifi初始化过程。
packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.java
public void onStart() {
super.onStart();
//创建WifiEnabler对象
// On/off switch is hidden for Setup Wizard (returns null)
mWifiEnabler = createWifiEnabler();
packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
// wifi开关
public boolean onSwitchToggled(boolean isChecked)
{
mWifiManager.setWifiEnabled(isChecked
根据wifi开关打开wifi.
frameworks/base/wifi/java/android/wifi/Wifimanager.java
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
WifiManger使用aidl和WifiService进行通行
frameworks/base/wifi/java/android/wifi/IWifiManager.aidl
boolean setWifiEnabled(String packageName, boolean enable);
// WifiService与WifiManager通信
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiService.java
public WifiService(Context context) {
super(context);
mImpl = new WifiServiceImpl(context, new WifiInjector(context), new WifiAsyncChannel(TAG));
}
frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiServiceImpl.java
WifiServiceImpl中实现WifiService的方法
public synchronized boolean setWifiEnabled(String packageName, boolean enable)
throws RemoteException {
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
return true;
调用WifiControll状态机发送消息
WifiControll接受消息并处理。
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java
WifiController状态机处理消息:CMD_WIFI_TOGGLED
WifiController(Context context, WifiStateMachine wsm, WifiSettingsStore wss,
WifiLockManager wifiLockManager, Looper looper, FrameworkFacade f,
WifiApConfigStore wacs) {
super(TAG, looper);
mFacade = f;
mContext = context;
mWifiStateMachine = wsm;
mSettingsStore = wss;
mWifiLockManager = wifiLockManager;
mWifiApConfigStore = wacs;
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null);
mIdleIntent = mFacade.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0);
// 初始化状态机,并添加状态
addState(mDefaultState);
addState(mApStaDisabledState, mDefaultState);
addState(mStaEnabledState, mDefaultState);
addState(mQcStaEnablingState, mDefaultState);
addState(mQcStaDisablingState, mDefaultState);
addState(mQcApEnablingState, mDefaultState);
addState(mQcApDisablingState, mDefaultState);
addState(mQcApStaEnablingState, mDefaultState);
addState(mQcApStaDisablingState, mDefaultState);
addState(mQcApStaEnabledState, mDefaultState);
addState(mDeviceActiveState, mStaEnabledState);
addState(mDeviceInactiveState, mStaEnabledState);
addState(mScanOnlyLockHeldState, mDeviceInactiveState);
addState(mFullLockHeldState, mDeviceInactiveState);
addState(mFullHighPerfLockHeldState, mDeviceInactiveState);
addState(mNoLockHeldState, mDeviceInactiveState);
addState(mStaDisabledWithScanState, mDefaultState);
addState(mApEnabledState, mDefaultState);
addState(mEcmState, mDefaultState);
// 判断飞行模式,wifi是否使能,是否打开了location wifi
boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();
log("isAirplaneModeOn = " + isAirplaneModeOn +
", isWifiEnabled = " + isWifiEnabled +
", isScanningAvailable = " + isScanningAlwaysAvailable);
// 设置wifi状态机的初始状态, isScanningAlwaysAvailable是打开了location wifi服务
if (isScanningAlwaysAvailable) {
setInitialState(mStaDisabledWithScanState);
} else {
setInitialState(mApStaDisabledState);
}
setLogRecSize(100);
setLogOnlyTransitions(false);
// 添加广播接收者,用于接收广播
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_DEVICE_IDLE);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
mContext.registerReceiver(
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_DEVICE_IDLE)) {
sendMessage(CMD_DEVICE_IDLE);
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
WifiManager.EXTRA_NETWORK_INFO);
} else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
int state = intent.getIntExtra(
WifiManager.EXTRA_WIFI_AP_STATE,
WifiManager.WIFI_AP_STATE_FAILED);
if (state == WifiManager.WIFI_AP_STATE_FAILED) {
loge(TAG + "SoftAP start failed");
sendMessage(CMD_AP_START_FAILURE);
} else if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
sendMessage(CMD_AP_STOPPED);
} else if (state == WifiManager.WIFI_AP_STATE_ENABLED) {
sendMessage(CMD_AP_STARTED);
}
} else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
int state = intent.getIntExtra(
WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN);
if (state == WifiManager.WIFI_STATE_UNKNOWN) {
loge(TAG + "Wifi turn on failed");
sendMessage(CMD_STA_START_FAILURE);
} else if (state == WifiManager.WIFI_STATE_ENABLED) {
sendMessage(CMD_WIFI_ENABLED);
} else if (state == WifiManager.WIFI_STATE_DISABLED) {
sendMessage(CMD_WIFI_DISABLED);
}
}
}
},
new IntentFilter(filter));
initializeAndRegisterForSettingsChange(looper);
}
// 先查看没有打开location wifi的情况
// 初始状态,切换状态首先进入enter函数
class ApStaDisabledState extends State {
private int mDeferredEnableSerialNumber = 0;
private boolean mHaveDeferredEnable = false;
private long mDisabledTimestamp;
@Override
public void enter() {
/*
* For STA+SAP concurrency request to stop supplicant is
* handled in QcStaDisablingState. Hence skip for standalone case.
*/
// 判断STA和AP是否并发
if (!mStaAndApConcurrency) {
mWifiStateMachine.setSupplicantRunning(false); // 关闭 wpa supplicant, 关闭的会延时一下在发送关闭的消息。
// Supplicant can't restart right away, so not the time we switched off
mDisabledTimestamp = SystemClock.elapsedRealtime();
mDeferredEnableSerialNumber++;
mHaveDeferredEnable = false; // 将消息设置为不可推迟。
mWifiStateMachine.clearANQPCache();
}
}
@Override
public boolean processMessage(Message msg) {
logStateAndMessage(msg, this);
switch (msg.what) {
case CMD_WIFI_TOGGLED: // 打开wifi发送的是CMD_WIFI_TOGGLED,这里处理这个消息
case CMD_AIRPLANE_TOGGLED:
if (mSettingsStore.isWifiToggleEnabled()) {
if (doDeferEnable(msg)) { // 判断是否使能了消息保留,没到就进入if
if (mHaveDeferredEnable) {
// have 2 toggles now, inc serial number an ignore both
mDeferredEnableSerialNumber++;
}
mHaveDeferredEnable = !mHaveDeferredEnable;
break;
}
if (mDeviceIdle == false) {
if (mStaAndApConcurrency) { // STA和AP并发
transitionTo(mQcStaEnablingState); // 切换到QcStaEnablingState状态
} else {
// wifi is toggled, we need to explicitly tell WifiStateMachine that we
// are headed to connect mode before going to the DeviceActiveState
// since that will start supplicant and WifiStateMachine may not know
// what state to head to (it might go to scan mode).
mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
// 切换到DeviceActiveState.
// 根据状态机的层级关系,需要先切换到其父类StaEnabledState,然后再切换到DeviceActiveState.
transitionTo(mDeviceActiveState);
}
} else {
checkLocksAndTransitionWhenDeviceIdle();
}
} else if (mSettingsStore.isScanAlwaysAvailable()) {
transitionTo(mStaDisabledWithScanState);
}
break;
case CMD_SCAN_ALWAYS_MODE_CHANGED:
if (mSettingsStore.isScanAlwaysAvailable()) { // loction wifi 打开,切换状态
transitionTo(mStaDisabledWithScanState);
}
break;
case CMD_SET_AP:
if (msg.arg1 == 1) {
if (msg.arg2 == 0) { // previous wifi state has not been saved yet
mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
}
/* For STA+SAP concurrency request to start SoftAP is handled in QcApEnablingState. */
if (mStaAndApConcurrency) {
transitionTo(mQcApEnablingState);
} else {
mWifiStateMachine.setHostApRunning((SoftApModeConfiguration) msg.obj,
true);
transitionTo(mApEnabledState);
}
}
break;
case CMD_DEFERRED_TOGGLE:
if (msg.arg1 != mDeferredEnableSerialNumber) {
log("DEFERRED_TOGGLE ignored due to serial mismatch");
break;
}
log("DEFERRED_TOGGLE handled");
sendMessage((Message)(msg.obj));
break;
case CMD_RESTART_WIFI_CONTINUE:
if (mStaAndApConcurrency) {
log("ApStaDisabledState: CMD_RESTART_WIFI_CONTINUE -> mQcStaEnablingState");
if (mRestartStaSapStack) {
deferMessage(msg);
}
transitionTo(mQcStaEnablingState);
} else {
transitionTo(mDeviceActiveState);
}
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
当WIFI的STA和AP都是关闭,并且没有并发,打开wifi开关,有上面可知,进入StaEnabledState状态。
class StaEnabledState extends State {
@Override
public void enter() {
/*
* For STA+SAP concurrency request to start supplicant is
* handled in QcStaEnablingState. Hence skip for standalone case
*/
// WifiStateMachine启动wpa_supplicant
if (!mStaAndApConcurrency) {
mWifiStateMachine.setSupplicantRunning(true);
}
}
@Override
public boolean processMessage(Message msg) {
logStateAndMessage(msg, this);
switch (msg.what) {
case CMD_WIFI_TOGGLED:
if (! mSettingsStore.isWifiToggleEnabled()) {
if (mSettingsStore.isScanAlwaysAvailable()) {
transitionTo(mStaDisabledWithScanState);
} else {
if (mStaAndApConcurrency) {
transitionTo(mQcStaDisablingState);
} else {
transitionTo(mApStaDisabledState);
}
}
}
break;
case CMD_AIRPLANE_TOGGLED:
/* When wi-fi is turned off due to airplane,
* disable entirely (including scan)
*/
if (!mSettingsStore.isWifiToggleEnabled()) {
if (mStaAndApConcurrency) {
transitionTo(mQcStaDisablingState);
} else {
transitionTo(mApStaDisabledState);
}
}
break;
case CMD_STA_START_FAILURE:
if (!mSettingsStore.isScanAlwaysAvailable()) {
transitionTo(mApStaDisabledState);
} else {
transitionTo(mStaDisabledWithScanState);
}
break;
case CMD_EMERGENCY_CALL_STATE_CHANGED:
case CMD_EMERGENCY_MODE_CHANGED:
boolean getConfigWiFiDisableInECBM = mFacade.getConfigWiFiDisableInECBM(mContext);
log("WifiController msg " + msg + " getConfigWiFiDisableInECBM "
+ getConfigWiFiDisableInECBM);
if ((msg.arg1 == 1) && getConfigWiFiDisableInECBM) {
transitionTo(mEcmState);
}
break;
case CMD_SET_AP:
if (msg.arg1 == 1) {
if (mStaAndApConcurrency) {
Slog.d(TAG,"StaEnabledState:CMD_SET_AP:setHostApRunning(true)-> mApStaEnableState");
mSoftApStateMachine.setHostApRunning(((SoftApModeConfiguration) msg.obj), true);
transitionTo(mQcApStaEnablingState);
} else {
// remeber that we were enabled
mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_ENABLED);
deferMessage(obtainMessage(msg.what, msg.arg1, 1, msg.obj));
transitionTo(mApStaDisabledState);
}
}
break;
case CMD_RESTART_WIFI:
if (mStaAndApConcurrency) {
log("StaEnabledState:CMD_RESTART_WIFI ->QcStaDisablingState");
deferMessage(obtainMessage(CMD_RESTART_WIFI_CONTINUE));
transitionTo(mQcStaDisablingState);
}
break;
case CMD_RESTART_WIFI_CONTINUE:
if (mStaAndApConcurrency && mRestartStaSapStack) {
if (msg.obj != null) {
log("StaEnabledState:CMD_RESTART_WIFI_CONTINUE ->mQcApStaEnablingState");
mSoftApStateMachine.setHostApRunning(((SoftApModeConfiguration) msg.obj), true);
transitionTo(mQcApStaEnablingState);
} else {
log("StaEnabledState:CMD_RESTART_WIFI_CONTINUE: SoftApConfig obj null. Do nothing");
}
mRestartStaSapStack = false;
}
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
}
// Wifi状态机启动supplicant
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
public void setSupplicantRunning(boolean enable)
sendMessage(CMD_START_SUPPLICANT);
WifiStateMachine在WifiInjector中创建
wifi状态机启动wpa_supplicant
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java
class InitialState extends State {
public boolean processMessage(Message message) {
logStateAndMessage(message, this);
switch (message.what) {
case CMD_START_SUPPLICANT:
Pair<Integer, IClientInterface> statusAndInterface =
mWifiNative.setupForClientMode();
if (statusAndInterface.first == WifiNative.SETUP_SUCCESS) {
mClientInterface = statusAndInterface.second;
} else {
incrementMetricsForSetupFailure(statusAndInterface.first);
}
if (mClientInterface == null
|| !mDeathRecipient.linkToDeath(mClientInterface.asBinder())) {
setWifiState(WifiManager.WIFI_STATE_UNKNOWN);
staCleanup();
break;
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
public Pair<Integer, IClientInterface> setupForClientMode() {
if (!startHalIfNecessary(true)) {
Log.e(mTAG, "Failed to start HAL for client mode");
return Pair.create(SETUP_FAILURE_HAL, null);
}
IClientInterface iClientInterface = mWificondControl.setupDriverForClientMode();
if (iClientInterface == null) {
return Pair.create(SETUP_FAILURE_WIFICOND, null);
}
return Pair.create(SETUP_SUCCESS, iClientInterface);
}
private boolean startHalIfNecessary(boolean isStaMode) {
if (!mWifiVendorHal.isVendorHalSupported()) {
Log.i(mTAG, "Vendor HAL not supported, Ignore start...");
return true;
}
if (mStaAndAPConcurrency)
return mWifiVendorHal.startConcurrentVendorHal(isStaMode);
return mWifiVendorHal.startVendorHal(isStaMode);
}
public boolean startVendorHal(boolean isStaMode) {
synchronized (sLock) {
if (mIWifiStaIface != null) return boolResult(false);
if (mIWifiApIface != null) return boolResult(false);
if (!mHalDeviceManager.start()) {
return startFailedTo("start the vendor HAL");
}
IWifiIface iface;
if (isStaMode) {
mIWifiStaIface = mHalDeviceManager.createStaIface(null, null);
if (mIWifiStaIface == null) {
return startFailedTo("create STA Iface");
}
iface = (IWifiIface) mIWifiStaIface;
if (!registerStaIfaceCallback()) {
return startFailedTo("register sta iface callback");
}
mIWifiRttController = mHalDeviceManager.createRttController(iface);
if (mIWifiRttController == null) {
return startFailedTo("create RTT controller");
}
if (!registerRttEventCallback()) {
return startFailedTo("register RTT iface callback");
}
enableLinkLayerStats();
} else {
mIWifiApIface = mHalDeviceManager.createApIface(null, null);
if (mIWifiApIface == null) {
return startFailedTo("create AP Iface");
}
iface = (IWifiIface) mIWifiApIface;
}
mIWifiChip = mHalDeviceManager.getChip(iface);
if (mIWifiChip == null) {
return startFailedTo("get the chip created for the Iface");
}
if (!registerChipCallback()) {
return startFailedTo("register chip callback");
}
mLog.i("Vendor Hal started successfully");
return true;
}
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManage.java
private IWifiIface createIface(int ifaceType, InterfaceDestroyedListener destroyedListener,
Looper looper) {
if (DBG) Log.d(TAG, "createIface: ifaceType=" + ifaceType);
synchronized (mLock) {
WifiChipInfo[] chipInfos = getAllChipInfo();
if (chipInfos == null) {
Log.e(TAG, "createIface: no chip info found");
stopWifi(); // major error: shutting down
return null;
}
if (!validateInterfaceCache(chipInfos)) {
Log.e(TAG, "createIface: local cache is invalid!");
stopWifi(); // major error: shutting down
return null;
}
IWifiIface iface = createIfaceIfPossible(chipInfos, ifaceType, destroyedListener,
looper);
if (iface != null) { // means that some configuration has changed
if (!dispatchAvailableForRequestListeners()) {
return null; // catastrophic failure - shut down
}
}
return iface;
}
private IWifiIface createIfaceIfPossible(WifiChipInfo[] chipInfos, int ifaceType,
InterfaceDestroyedListener destroyedListener, Looper looper) {
IWifiIface iface = executeChipReconfiguration(bestIfaceCreationProposal, ifaceType);
WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(
ifaceCreationData.chipModeId);
hardware\interfaces\wifi\1.1\default\wifi_chip.cpp
Return<void> WifiChip::configureChip(ChipModeId mode_id,
configureChip_cb hidl_status_cb) {
return validateAndCall(this,
WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
&WifiChip::configureChipInternal,
hidl_status_cb,
mode_id);
}
WifiStatus WifiChip::configureChipInternal(ChipModeId mode_id) {
if (mode_id != kStaChipModeId && mode_id != kApChipModeId) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
if (mode_id == current_mode_id_) {
LOG(DEBUG) << "Already in the specified mode " << mode_id;
return createWifiStatus(WifiStatusCode::SUCCESS);
}
WifiStatus status = handleChipConfiguration(mode_id);
if (status.code != WifiStatusCode::SUCCESS) {
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onChipReconfigureFailure(status).isOk()) {
LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
}
}
return status;
}
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onChipReconfigured(mode_id).isOk()) {
LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
}
}
current_mode_id_ = mode_id;
return status;
}
hardware\interfaces\wifi\1.1\default\wifi_mode_controller.cpp
WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id) {
// If the chip is already configured in a different mode, stop
// the legacy HAL and then start it after firmware mode change.
// Currently the underlying implementation has a deadlock issue.
// We should return ERROR_NOT_SUPPORTED if chip is already configured in
// a different mode.
// handleChipConfiguration assumes that initial mode is kInvalidModeId.
// This limitation is not applicable for wifiStaSapConcurrency feature.
if (!(WifiFeatureFlags::wifiStaSapConcurrency) &&
current_mode_id_ != kInvalidModeId) {
// TODO(b/37446050): Fix the deadlock.
return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
}
bool success;
if (mode_id == kStaChipModeId) {
success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
} else {
success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
}
if (!success) {
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
}
legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to start legacy HAL: "
<< legacyErrorToString(legacy_status);
return createWifiStatusFromLegacyError(legacy_status);
}
return createWifiStatus(WifiStatusCode::SUCCESS);
}
bool WifiModeController::changeFirmwareMode(IfaceType type) {
if (!driver_tool_->LoadDriver()) { // 加载驱动
LOG(ERROR) << "Failed to load WiFi driver";
return false;
}
if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) {
LOG(ERROR) << "Failed to change firmware mode";
return false;
}
return true;
}
frameworks\opt\net\wifi\libwifi_hal\driver_tool.cpp
frameworks\opt\net\wifi\libwifi_hal\driver_tool.cpp
bool DriverTool::LoadDriver() {
return ::wifi_load_driver() == 0;
}
frameworks\opt\net\wifi\libwifi_hal\wifi_hal_common.cpp
int wifi_load_driver() {
#ifdef WIFI_DRIVER_MODULE_PATH
if (is_wifi_driver_loaded()) {
return 0;
}
if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) return -1;
#endif
#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
if (is_wifi_driver_loaded()) {
return 0;
}
if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) return -1;
#endif
property_set(DRIVER_PROP_NAME, "ok");
return 0;
}
Android 8 Wifi 初始化过程的更多相关文章
- android kernel控制台初始化过程
对于我们的android平台,控制台被定义到了串口1上,因此初始化过程就是把控制台的输出配置到串口1上 对kernel控制台初始化是在挂载文件系统之前,由于没有串口的设备文件,不能通过打开设备文件来访 ...
- Android编译系统环境初始化过程分析
Android源代码在编译之前,要先对编译环境进行初始化,其中最主要就是指定编译的类型和目标设备的型号.Android的编译类型主要有eng.userdebug和user三种,而支持的目标设备型号则是 ...
- android 8 wifi wifi 扫描过程
查看一下android wifi扫描的过程. packages\apps\Settings\src\com\android\settings\wifi\WifiSettings.java public ...
- Android(java)学习笔记159:Dalivk虚拟机的初始化过程
1.初始化下面系统函数(调用dvmStartup函数初始化所有相关的函数) 开始学习虚拟机的初始化过程,先从dvmStartup函数开始,这个函数实现所有开始虚拟机的准备工作: dvmAllocTra ...
- Android(java)学习笔记102:Dalivk虚拟机的初始化过程
1. 初始化下面系统函数(调用dvmStartup函数初始化所有相关的函数) 开始学习虚拟机的初始化过程,先从dvmStartup函数开始,这个函数实现所有开始虚拟机的准备工作: dvmAllo ...
- android绘制view的过程
1 android绘制view的过程简单描述 简单描述可以解释为:计算大小(measure),布局坐标计算(layout),绘制到屏幕(draw): 下面看看每一步的动作到底是 ...
- android.net.wifi的简单使用方法
获取Wifi的控制类WifiManager. WifiManager wm=(WifiManager)getSystemService(Context.WIFI_SERVICE); 接下来可以对w ...
- 【转】Android绘制View的过程研究——计算View的大小
Android绘制View的过程研究——计算View的大小 转自:http://liujianqiao398.blog.163.com/blog/static/18182725720121023218 ...
- Android打开WIFI或者移动网络的代码实现
MainActivity如下: package wy.testnetwork; import java.lang.reflect.Field; import java.lang.reflect.Inv ...
随机推荐
- 笔记 Hadoop
今天有缘看到董西成写的<Hadoop技术内幕:深入解析MapReduce架构设计与实现原理>,翻了翻觉得是很有趣的而且把hadoop讲得很清晰书,就花了一下午的时间大致拜读了一下(仅浏览了 ...
- .NET MVC5+ Dapper+扩展+AutoFac自动注入实现
1.首先创建一个MVC项目 定义Model 层 view 层 index.cshtml 控制器层Controllers等文件 2.在线安装或者引用dapper 以及扩展相关包 同时Autofac ...
- 【Linux】了解服务器的情况
Java程序大多数都部署在Unix环境,而环境的稳定性对于部署的应用至关重要,所以Java开发人员需知道了解Unix环境的命令. 系统版本 查看系统版本 [root@localhost third_p ...
- NGUI的UISprite动态染色的一种方法
本文主要参考iwinterice 的 NGUI的UISprite动态染色的一种解决方案 文章. 参考参考,就是既参详又拷贝,-,-||| 相关理论依据,还请去移步 NGUI的UISprite动态染色的 ...
- 【Android】Sensor框架HAL层解读
Android sensor构建 Android4.1 系统内置对传感器的支持达13种,他们分别是:加速度传感器(accelerometer).磁力传感器(magnetic field).方向传感器( ...
- 【Linux技术】autotools制作makefile过程详解
Preface Makefile固然可以帮助make完成它的使命,但要承认的是,编写Makefile确实不是一件轻松的事,尤其对于一个较大的项目而言更是如此.那么,有没有一种轻松的手段生成Makefi ...
- Android下基于PCM的音频渲染
环境准备 请按照我之前的文章-Android下基于SDL的位图渲染,安装必要的开发环境. 实践篇 这里主要参考Beginning SDL 2.0(6) 音频渲染及wav播放,只不过将源从WAV文件改成 ...
- LeetCode: Add Two Numbers 解题报告
Add Two NumbersYou are given two linked lists representing two non-negative numbers. The digits are ...
- java 多线程 25 :线程和线程组的异常处理
线程中出现异常 从上面代码可以看出来处理线程的异常 设置异常的两种方式 1.全局异常,也是静态异常,是个静态方法 , 类.setDefaultUncaughtExceptionHandler() 2. ...
- java多线程16:join()的使用
讲解join()方法之前请确保对于即wait()/notify()/notifyAll()机制已熟练掌握.可以参考前面的笔记 join()方法的作用是等待线程销毁.join()方法反应的是一个很现实的 ...