当前位置:  编程技术>移动开发
本页文章导读:
    ▪Kconfig,Makefile 跟 .config        Kconfig,Makefile 和 .config        最新在做Sensor驱动移植的时候,发现了Android driver 中有Kconfig,Makefile文件。在查看编译后的文件时,又发现还存在.config文件。自己对这几个文件不明白,用度娘.........
    ▪ Win8开发疑义与解答        Win8开发疑问与解答疑问:怎样获取开发者许可证 打开VS2012时,怎么在没有取得开发者许可证之前,屏蔽/跳过弹出的窗体“获取Windows8开发者许可证 你需要具有开发者许可证才能开发适用于...........
    ▪ Coroutine,您究竟干了什么       Coroutine,你究竟干了什么?  一 引子   使用Unity已经有一段时间了,对于Component、GameObject之类的概念也算是有所了解,而脚本方面从一开始就选定了C#,目前来看还是挺明智的:Boo太小众.........

[1]Kconfig,Makefile 跟 .config
    来源: 互联网  发布时间: 2014-02-18
Kconfig,Makefile 和 .config

        最新在做Sensor驱动移植的时候,发现了Android driver 中有Kconfig,Makefile文件。在查看编译后的文件时,又发现还存在.config文件。自己对这几个文件不明白,用度娘来整理下网友对这几个文件的理解。

        分布在各目录下的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。在内核配置make menuconfig(或xconfig等)时,从Kconfig中读出配置菜单,用户配置完后保存到.config(在顶层目录下生成)中。在内核编译时,主Makefile调用这个.config,就知道了用户对内核的配置情况。Kconfig就是对应着内核的配置菜单。假如要想添加新的驱动到内核的源码中,可以通过修改Kconfig来增加对我们驱动的配置菜单,这样就有途径选择我们的驱动,假如想使这个驱动被编译,还要修改该驱动所在目录下的Makefile。

Kconfig

    先来看下一个相对完整的Kconfig文件:

menuconfig MISC_DEVICES
        bool "Misc devices"
        ---help---
          Say Y here to get to see options for device drivers from various
          different categories. This option alone does not add any kernel code.

          If you say N, all options in this submenu will be skipped and disabled.

if MISC_DEVICES

config ST_L3GD20_GYR
        tristate "L3GD20_GYR gyroscope sensor support"
        depends on I2C=y
        help
          If you say yes here you get support for ST's
          gyroscope sensors L3GD20_GYR.

choice
        prompt "Preemption Model"
        depends on SENSORS_AFA750
        default CALI_NONE

config CALI_NONE
        bool "None"
        help
          Say yes here to disable calibration function for AFA750

config CALI_POSITIVE
        bool "positive calibration"
        help
          Say yes here when the afa750 and LCD are laid towared the same direction on your board

endchoice

config SENSORS_LSM303D
        tristate "LSM303 sensor driver"
        depends on I2C=y
        help
          Say yes here to support the sensor

endif
1.语法:
           config   symbol
                         options
           symbol是一个新的标记的菜单项,options是在这个新的菜单项下的属性和选项。

2.菜单结构:

          配置文件描述了菜单选项,每行都是以一关键字开头(除了帮助信息)。下面的关键字结束一菜单选项:
         - config
        - menuconfig
        - choice/endchoice
        - comment
        - menu/endmenu
        - if/endif
        - source
2.options类型定义:
        每个config菜单项都要有类型定义:bool布尔类型、 tristate三态(内建、模块、移除)、 string字符串、 hex十六进制、 integer整型。

        例如:

config CALI_NONE
        bool "None"

         bool类型的只能选中或不选中,tristate类型的菜单项多了编译成内核模块的选项,如果选择编译成内核模块,则会在.config中生成一个CONFIG_CALI_NONEE=m的配置,如果选择内建,就是直接编译成内核影响,就会在.config中生成一个CONFIG_CALI_NONE=y的配置.

3.依赖型定义depends on或requires
           指此菜单的出现与否依赖于另一个定义

config SENSORS_LSM303D
            tristate "LSM303 sensor driver"
             depends on I2C=y
          这个例子表明SENSORS_LSM303D这个菜单项只I2C有效。

4.select与depends on是相反的逻辑关系。
           A depends on B
           那么只有在B选中才能选A
           A select B
          那么只要选中A就会选中B
5.帮助性定义
           只是增加帮助用关键字help或者---help---,"---help---" 和 "help" 在实现的作用上没有区别,"---help---" 有助于将文件中的配置逻辑与给开发人员的提示分开。

6.prompt --输入提示

Makefile

1.顶层的Makefile文档读取 .config文档的内容,并总体上负责build内核和模块。
2.Arch Makefile则提供补充体系结构相关的信息。 
3.scripts目录下的Makefile文档包含了任何用来根据kbuild Makefile 构建内核所需的定义和规则。
            其中.config的内容是在make menuconfig的时候,通过Kconfig文档配置的结果,在/Documentation/kbuild目录下有详细的介绍有关kernel makefile的知识。

举个例子:

假设想把G-sensor LSM303D驱动code加载到工程中,配置内核时该怎么办呢?
1:将您写的lsm303d.c 文档添加到/driver/misc/ 目录下。
2:修改/driver/misc/ 目录下的kconfig文档:

config SENSORS_LSM303D
        tristate "LSM303 sensor driver"
        depends on I2C=y
        help
          Say yes here to support the sensor
3:修改该目录下makefile文档。
添加code:
 obj-$(CONFIG_SENSORS_LSM303D)   += lsm303d.o
从上述分析知道CONFIG_SENSORS_LSM303D 是从.config 中读出的。
4.配置kernel下configs/XXXX_defconfig文件
添加code:
CONFIG_SENSORS_LSM303D=y
当您编译内核时,将会读取.config文档,当发现CONFIG_SENSORS_LSM303D=y,系统在调用/driver/misc下的makefile 时,将会把 lsm303d.o 加入到内核中。即可达到您的目的。


主要参考文章:http://blog.sina.com.cn/s/blog_4a377e150100c896.html


    
[2] Win8开发疑义与解答
    来源: 互联网  发布时间: 2014-02-18
Win8开发疑问与解答
疑问:怎样获取开发者许可证

打开VS2012时,怎么在没有取得开发者许可证之前,屏蔽/跳过弹出的窗体“获取Windows8开发者许可证 你需要具有开发者许可证才能开发适用于......”

打开Blend for Visual Studio 2012时弹出的窗体“无法获取windows开发人员许可证。错误代码:800704C7。是否要重新尝试获取许可证?“

解答:

在本地计算机上首次运行 Microsoft Visual Studio 2012 时,系统会提示你获取开发者许可证。请阅读许可条款,然后单击“我同意”。在“用户账户控制(UAC)”对话框中,单击“是”以继续。在本地计算机上安装许可证后,系统不会在该计算机上再次进行提示。你可以在使用 Visual Studio IDE 的任何时间续订你的开发者许可证。

获取之后会弹出如下窗体,一次有效期只有一个月:

 

疑问:Windows 8与 Windows Phone 8 应用兼容吗

Windows 8 作为一款同时支持平板电脑与传统PC 的系统平台。此外,微软还同步推出了基于智能手机平台的新一代Windows Phone 8 移动操作系统,并实现传统PC、平板电脑、智能手机3 个平台的完美融合。

那Windows 8与 Windows Phone 8 应用兼容吗

解答:

WP8跟WIN8用的是相同的内核,开发者可以WIN8的应用轻松移植到WP8上,所以如果开发者不移植的话,WP8还是不可以直接使用WIN8的应用,但是这个移植过程相对是很简单和轻松的,所以一般的开发者都会移植的

 

疑问:Win8新特性让微软全球开发者感到担心

对于Windows程序开发人员而言,他们大多花费了大量的精力和资金投入微软的平台,学习例如Win32、COM组件、.NET框架、 Silverlight和WPF等,他们获得专长的时间长达数十年,而微软Windows 8大量使用HTML5和JavaScript的现状会让他们需要花费时间重新适应最新的技术,这非常令人沮丧。
而对于微软而言,转化到HTML5和JavaScript将意味着他们要抛弃数十年来积累的强大Windows框架、Visual Studio开发环境和各种资源,在一个简陋的工具和系统结构下重起炉灶。

解答:

Windows 8中HTML5和JavaScript只是一种程序开发选择,微软并没有彻底抛弃.NET的开发者。

Windows8的开发框架并没有基于HTML5和JavaScript,开发者完全可以用原生C++、C#和Silverlight去开发对平板和触控友好的应用,HTML5和JavaScript只是提供了一种选择。

 

疑问:VS2012开发Metro界面的Win8应用界面怎么退出?

Win8下,VS2012开发Metro界面的Win8应用,运行之后界面怎么退出?

解答:

鼠标移到窗口最上方,变成一个手掌,点击鼠标左键并保持,把整个窗口拉到屏幕最下方,就关闭了。

鼠标偏左或者偏右,会有WIN切换

 

 

 

 

 

 

作者:水煮鱼
出处:http://blog.csdn.net/panfb227


    
[3] Coroutine,您究竟干了什么
    来源: 互联网  发布时间: 2014-02-18
Coroutine,你究竟干了什么?

  一 引子

  使用Unity已经有一段时间了,对于Component、GameObject之类的概念也算是有所了解,而脚本方面从一开始就选定了C#,目前来看还是挺明智的:Boo太小众,而且支持有限;JS(或着说UnityScript)的话稍稍自由散漫了些,不太符合我们这些略显严谨的程序猿;相比之下,C#各方面都十分沁人心腑,使用起来还是相当舒畅的 :)

  就游戏开发而言,Unity也确实为我们减轻了不少开发负担、缩短了很多开发流程,但从开发原理上来讲,使用Unity你仍然避不开许多传统的开发技术,譬如几乎所有游戏程序都有的Update,在Unity里就变成了MonoBehaviour的一个成员方法;而另一个几乎与Update并重的Init方法,在Unity里则被换成了Start。可以这么说,Unity虽然极大的简化了游戏开发流程,但从方法原理上来讲的话,其实他也并没有和传统开发方式存在非常大的差异,Update还是那个Update,Init还是那个Init,只不过换了一个更简单的形式而已~

  依此思路,我持续着自己的Unity学习之路,也逐步验证着自己上述的观点,直到有一天,我遇到了Coroutine ……

  二. Coroutine是什么?

  延时大概是游戏编程中最司空见惯的需求之一:角色移动控制需要延时、事件触发需要延时、甚至开启一个粒子特效有时也需要延时,可以说,延时在游戏开发中几乎无处不在 :)有鉴于此,很多的游戏引擎对于延时控制都提供了很好的支持,譬如在cocos2d-x中,CCDelayTime就是专门用来干这个的,当然,其他引擎也有自己不同的支持方式,但是从实现层面来讲,基本都是“标记开始时间,Update中持续更新检查”这种方法,从代码上来看,大抵是这么一个样子:

  float delayTime = <time value to delay>;
  float elapsedTime = 0;
            
  void Update(float frameTime) {
      if (elapsedTime >= delayTime) {
          // delay is over here ...
      }
      else {
          elapsedTime += frameTime;
       }
  }

  而在Unity中,我们自然也可以使用这种方法来进行延时,但是相对而言,这种方法并不是最佳实践,更好的在Unity中实现延时的做法是使用Coroutine,就代码上来看的话,大概是这个样子:

  IEnumerator DelayCoroutine() {

// work before delay

yield return new WaitForSeconds(<time value to delay>);

// work after delay

}

  StartCoroutine(DelayCoroutine());

  没有什么elapsedTime之类的变量,甚至没有什么Update,你要做的就是写一个以IEnumerator为返回类型的方法,然后在其中使用yield return这种语法来返回一个WaitForSeconds类型的实例,实例的构造参数就是你想要延时的时间,然后在需要的时候,调用StartCoroutine来进行延时即可。

  面对这种从未见过的延时实现方式,虽然代码表达上很容易让人理解,一开始的我却显得有些抵触,首先的一个疑问就是:这Coroutine是什么?从字面意思上来理解,Coroutine应该就是“协程”的意思,而这所谓的“协程”又是什么东西?第一个想到的便是Lua中“协程”,Unity中的Coroutine难道也是这个概念吗?另外的,这Unity“协程”跟线程又是一个什么关系,就其可以进行延时而不影响其他逻辑运行这个特性来看,“协程”是否就是C#线程的一个封装呢?第二个疑问就是返回类型IEnumerator,名字奇怪也就罢了,我还需要使用yield return这种奇怪的方式来进行返回,而且貌似WaitForSeconds也并不是一个所谓IEnumerator的类型,怎么就可以正常返回呢?第三个疑问,也是最大的一个疑问就是:虽然WaitForSeconds这个类型的名称意义一目了然,但就实现层面来看,其是如何做到延时这项功能的着实让人摸不着头脑……

  三. Coroutine大概是这个样子的……

  随着自己对C#有了进一步的了解,我才慢慢发现,上面所言的那两个奇怪的IEnumerator和yield return,其实并不是Unity的什么独创,相反,他们却是C#中到处可见的迭代器的构造方式(之一),你也许对于迭代器这个东西没什么印象,但实际上,我们可能天天都在使用它!让我们马上来看一个最普遍的迭代器运用:

  int[] array = new int[] {1, 2, 3, 4, 5};
            
  foreach (int val in array) {
      // do something
  }

  代码非常简单,不过是使用foreach来遍历一个整型数组,而代码中我们早已习以为常的foreach其实就是迭代器的语法糖,在真正的运行代码中,C#的编译器会将上面的代码改头换面成这个样子:

  int[] array = new int[] {1, 2, 3, 4, 5};
            
  IEnumerator e = array.GetEnumerator();
  while (e.MoveNext()) {
      // do something
  }

  上述代码首先通过array的GetEnumerator方法来获取array的一个“迭代器”,然后通过“迭代器”的MoveNext方法进行依次遍历,而这“迭代器”实际上就是之前那个稍显奇怪的IEnumerator类型!而至于yield return,其实是C# 2.0新引进的一种实现迭代器模式的简便语法,在之前的C# 1.0中,如果要实现一个完整的迭代器,我们必须要分别实现IEnumerable和IEnumerator这两个接口,过程略显枯燥繁琐,而借助yield return,这两个步骤我们都可以省略!譬如我们写下了如下的代码:

IEnumerator Test() {
    yield return 1;
    yield return 2;
    yield return 3;
}

那么C#编译器就会帮你自动生成类似下面的这些代码(不准确,仅作示意):

public class InnerEnumerable : IEnumerable {
    public class InnerEnumerator : IEnumerator {
        int[] array = new int[] {1, 2, 3};
        int currentIndex = -1;
                
        public bool MoveNext() {
            ++currentIndex;
            return currentIndex < array.Length;
        }
                
        public Object Current {
            get { return array[currentIndex]; }
        }
                    
        public void Reset() {
            throw new Exception("unsurport");
        }
    }
            

public IEnumerator GetEnumerator() {
        return new InnerEnumerator();
    }
}        
        

IEnumerator Test() {
     InnerEnumerable e = new InnerEnumerable();
     return e.GetEnumerator();
 }

  当然,实际的迭代器代码实现远非如此简单,但原理上基本可以看做是一个有限状态机,有兴趣的朋友可以看看更深入的一些介绍,譬如这里和这里。

  OK,让我们继续回到Unity,通过上面的这些分析,我们大概就肯定了这么一点:Unity其实是使用了迭代器来实现延时的,像IEnumerator、yield return等的使用皆是为了配合C#中迭代器的语法,其与什么多线程之类的概念并没有多少关系,但是目前我仍然还是不能理解之前的那个最大疑问:虽然迭代器可以保留运行状态以便下次继续往下运行,但是他本身并没有提供什么机制来达到延时之类的效果,像foreach这种语句,虽然使用了迭代器,但实际上也是一股脑儿运行完毕的,并不存在延时一说,那么在Unity中,为什么简单的返回一个WaitForSeconds就可以呢?

  三 Coroutine原来如此 :)

  看来答案应该是在WaitForSeconds这个类型身上了~经过简单的一些搜索,我找到了这么一篇帖子,内容便是如何自己实现一个简单的WaitForSeconds,大体上的思路便是使用循环yield return null这种方法来达到延时的目的,直接抄一段帖子中的示例代码:

using UnityEngine; 

using System.Collections; 

 

public class TimerTest : MonoBehaviour { 

    IEnumerator Start () {

        yield return StartCoroutine(MyWaitFunction (1.0f));

        print ("1");

        yield return StartCoroutine(MyWaitFunction (2.0f));

        print ("2");

    }

 

    IEnumerator MyWaitFunction (float delay) {

        float timer = Time.time + delay;

        while (Time.time < timer) {

            yield return null;

        }

    }

}

  也就是说,如果我们在代码中写下了如下的延时语句:

   yield return WaitForSeconds(1.0f);

  那么在逻辑上,其大概等价于下面的这些语句:

   float timer = Time.time + 1.0f;

   while (Time.time < timer) {

       yield return null;

   }

  而完成这些操作的,很可能便是WaitForSeconds的构造函数,因为每次延时我们都就地生成(new)了一个WaitForSeconds实例。

  然而使用ILSpy查看WaitForSeconds实现源码的结果却又让我迷惑:WaitForSeconds的构造函数非常简单,似乎仅是记录一个时间变量罢了,根本就不存在什么While、yield之类的东西,而其父类YieldInstruction则更简单,就是单纯的一个空类……另外的,WWW这个Unity内建类型的使用方式也同样让我不解:

using UnityEngine;

using System.Collections;

public class Example : MonoBehaviour {

    public string url = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg";

    IEnumerator Start() {

        WWW www = new WWW(url);

        yield return www;

        renderer.material.mainTexture = www.texture;

    }

}

  在上面的示例代码中,yield return www;这条语句可以做到直到url对应资源下载完毕才继续往下运行(迭代),效果上类似于WaitForSeconds,但是WWW本身却又不像WaitForSeconds那样是个YieldInstruction,而且在使用上也是首先创建实例,然后直接yield 返回引用,按照这种做法,即便WWW的构造函数使用了上面的那种循环yield return null的方法,实际上也达不到我们想要的等待效果;再者便是语法上的一些细节,首先如果我们需要使用yield return的话,返回类型就必须是IEnumerable(<T>)或者IEnumerator(<T>)之一,而C#中的构造函数是没有返回值的,显然不符合这个原则,所以实际上在构造函数中我们无法使用什么yield return,另外的一点,虽然上述帖子中的方法可以实现自己的延时操作,但每次都必须进行StartCoroutine操作(如果没有也起不到延时效果),这一点也与一般的WaitForSeconds使用存在差异……

  后来看到了这篇文章,才大抵让我有所释怀:之前自己的种种猜测都聚焦在类似WaitForSeconds这些个特殊类型之上,一直以为这些类型肯定存在某些个猫腻,但实际上,这些类型(WaitForSeconds、WWW之类)都是“非常正常”的类型,并没有什么与众不同之处,而让他们显得与众不同的,其实是StartCoroutine这个我过去一直忽略的家伙!

  原理其实很简单,WaitForSeconds本身是一个普通的类型,但是在StartCoroutine中,其被特殊对待了,一般而言,StartCoroutine就是简单的对某个IEnumerator 进行MoveNext()操作,但如果他发现IEnumerator其实是一个WaitForSeconds类型的话,那么他就会进行特殊等待,一直等到WaitForSeconds延时结束了,才进行正常的MoveNext调用,而至于WWW或者WaitForFixedUpdate等类型,StartCoroutine也是同样的特殊处理,如果用代码表示一下的话,大概是这个样子:

 

foreach(IEnumerator coroutine in coroutines)

{

    if(!coroutine.MoveNext())

        // This coroutine has finished

        continue;

 

    if(!coroutine.Current is YieldInstruction)

    {

        // This coroutine yielded null, or some other value we don't understand; run it next frame.

        continue;

    }

 

    if(coroutine.Current is WaitForSeconds)

    {

        // update WaitForSeconds time value

    }

    else if(coroutine.Current is WaitForEndOfFrame)

    {

        // this iterator will MoveNext() at the end of the frame

    }

    else /* similar stuff for other YieldInstruction subtypes or WWW etc. */

}

基于上述理论,我们就可以来实现自己的WaitForSeconds了:

首先是CoroutineManager,我们通过他来实现类似于StartCoroutine的功能:

//

//    <maintainer>Hugo</maintainer>

//    <summary>simple coroutine manager class</summary>

//

using UnityEngine;

using System.Collections.Generic;

public class CoroutineManager : MonoBehaviour {

public static CoroutineManager Instance {

    get;

private set;

}

List<System.Collections.IEnumerator> m_enumerators = new List<System.Collections.IEnumerator>();

List<System.Collections.IEnumerator> m_enumeratorsBuffer = new List<System.Collections.IEnumerator>();

void Awake() {

    if (Instance == null) {

    Instance = this;

}

else {

    Debug.LogError("Multi-instances of CoroutineManager");

}

}

void LateUpdate() {

    for (int i = 0; i < m_enumerators.Count; ++i) {

// handle special enumerator

if (m_enumerators[i].Current is CoroutineYieldInstruction) {

    CoroutineYieldInstruction yieldInstruction = m_enumerators[i].Current as CoroutineYieldInstruction;

if (!yieldInstruction.IsDone()) {

    continue;

}

}

// other special enumerator here ...

// do normal move next

if (!m_enumerators[i].MoveNext()) {

    m_enumeratorsBuffer.Add(m_enumerators[i]);

continue;

}

}

// remove end enumerator

for (int i = 0; i < m_enumeratorsBuffer.Count; ++i) {

    m_enumerators.Remove(m_enumeratorsBuffer[i]);

}

m_enumeratorsBuffer.Clear();

}

public void StartCoroutineSimple(System.Collections.IEnumerator enumerator) {

m_enumerators.Add(enumerator);

}

}

接着便是我们自己的WaitForSeconds了,不过在此之前我们先来实现WaitForSeconds的基类,CoroutineYieldInstruction:

//

//    <maintainer>Hugo</maintainer>

//    <summary>coroutine yield instruction base class</summary>

//

using UnityEngine;

using System.Collections;

public class CoroutineYieldInstruction {

public virtual bool IsDone() {

    return true;

}

}

  很简单不是吗?类型仅有一个虚拟的IsDone方法,上面的CoroutineManager就是依据此来进行迭代器迭代的,OK,该是我们的WaitForSeconds上场了:

//

//    <maintainer>Hugo</maintainer>

//    <summary>coroutine wait for seconds class</summary>

//

using UnityEngine;

using System.Collections;

public class CoroutineWaitForSeconds : CoroutineYieldInstruction {

float m_waitTime;

float m_startTime;

public CoroutineWaitForSeconds(float waitTime) {

m_waitTime = waitTime;

m_startTime = -1;

}

public override bool IsDone() {

// NOTE: a little tricky here

if (m_startTime < 0) {

    m_startTime = Time.time;

}

// check elapsed time

return (Time.time - m_startTime) >= m_waitTime;

}

}

原理非常简单,每次IsDone调用时进行累时,直到延时结束,就这么简单 :)

写个简单的案例来测试一下:

//

//    <maintainer>Hugo</maintainer>

//    <summary>coroutine test case</summary>

//

using UnityEngine;

using System.Collections;

public class CoroutineTest: MonoBehaviour {

void Start() {

// start unity coroutine

StartCoroutine(UnityCoroutine());

    // start self coroutine

CoroutineManager.Instance.StartCoroutineSimple(SelfCoroutine());

}

IEnumerator UnityCoroutine() {

Debug.Log("Unity coroutine begin at time : " + Time.time);

yield return new WaitForSeconds(5);

Debug.Log("Unity coroutine begin at time : " + Time.time);

}

IEnumerator SelfCoroutine() {

Debug.Log("Self coroutine begin at time : " + Time.time);

yield return new CoroutineWaitForSeconds(5);

Debug.Log("Self coroutine begin at time : " + Time.time);

}

}

效果虽然不如原生的WaitForSeconds那么精确,但也基本符合期望,简单给张截图:

四 尾声

  Coroutine这个东西对于我来说确实比较陌生,其中的迭代原理也困扰了我许久,不少抵触情绪也“油然而生”(在此自我反省一下),但是经过简单的一阵子试用,我却赫然发现自己竟然离不开他了!究其原因,可能是其简洁高效的特性深深折服了我,想想以前那些个分散于代码各处的计时变量和事件逻辑,现在统统都可以做成一个个Coroutine,不仅易于理解而且十分高效,我相信不管是谁,在实际使用了Unity中的Coroutine之后,都会对他爱不释手的~ :)当然,这么好的东西网上自然早以有了非常优秀的介绍,有兴趣的朋友可以仔细看看 :)

  好了,就这样吧,下次再见了~

  

  

  


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
论坛 iis7站长之家
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3