当前位置:  ▪Android获取当前已连接的wifi信号强度的方法 iis7站长之家
本页文章导读:
    ▪XCode 运用国际化设置        XCode 应用国际化设置 1.本地化应用程序中的字符串 1.创建字符串文件 (1)在Supporting Files包下新建一个String File。步骤如下:           注意:将文件命名为Localizable.strings (2)添加.........
    ▪ kobject之kobject_uevent.c资料分析        kobject之kobject_uevent.c文件分析 struct      kset_uevent_ops {        int                 (*filter)(struct kset *kset, struct kobject *kobj);          //过滤函数,kset中的kobj是否需要处理      .........
    ▪ [Arduino 课程] BareMinimum-从零开始       [Arduino 教程] BareMinimum-从零开始原文:http://arduino.cc/en/Tutorial/BareMinimum 译文:http://blog.csdn.net/qffj/article/details/8184332 从最简单的代码开始 硬件需求 Arduino 开发板 编码 当 sketch 开始时se.........

[1]XCode 运用国际化设置
    来源: 互联网  发布时间: 2014-02-18
XCode 应用国际化设置
1.本地化应用程序中的字符串

1.创建字符串文件

(1)在Supporting Files包下新建一个String File。步骤如下:

 

        注意:将文件命名为Localizable.strings

(2)添加国际化文件。

        选中Localizable.strings文件,打开File Inspector,添加想要显示的语言的语种。如英语--en,简体中文--Chinese(zh-Hans),繁体中文--  Chinese(zh-Hans)等。

(3)编写国际化文件内容

     格式为"Key" = "Value";注意要带引号和结尾的分好。引号和分号均是英文拼写。

如在英文包中可以这样写:"hello" = "Hello Word!";

在中文报中可以这样写:"hello" = "偶其实还是很漂亮的!";

(4)使用国际化语言

在需要使用的地方用 NSLocalizedString(@"Key",comment);即可。

如下:

  • self.label.text = NSLocalizedString(@"hello", @"can''t find resource file!"); 
  • 如果找不到对应的国际化语言文件,则显示默认的开发语言。一般都是英文的。

    接下来运行既可以。 

    (5)如果想本地化storyboard的话步骤相同。只是多了一个某个语种的storyboard,重新做一下就行了。

    2.本地化应用程序配置文件info.plist,例如应用的名称

    创建应用程序的时候通常xcode会自动产生一个InfoPlist.strings文件,他可以用于本地化info.plist中的一些文字配置内容。例如可以本地化info.plist中写应用程序的名称。同样是添加语种文件,如简体中文和英文。方法同上。

    展开InfoPlist.strings文件左侧的三角符号可以看到有两个文件分别是代表语种文件中文和英文的。在文件中写如下代码:

  • CFBundleDisplayName = "国际化语言"; //CFBundleDisplayName应用程序完整名
  • 如果应用程序名过长,会自动截断,可以用简写名:CFBoundleName来设置。
     

    在网上看到好多都人都写到还要更改配置xxxx-Info.plist文件,说需要添加一个属性:Application hasl localized display name 并将其设置为YES.但是我没对编辑info.plist文件,照样可以正常显示。也就是说不用添加该属性也是可以的。

    结构如下图:

     


        
    [2] kobject之kobject_uevent.c资料分析
        来源: 互联网  发布时间: 2014-02-18
    kobject之kobject_uevent.c文件分析

    struct      kset_uevent_ops {

           int                 (*filter)(struct kset *kset, struct kobject *kobj);          //过滤函数,kset中的kobj是否需要处理

           const char      *(*name)(struct kset *kset, struct kobject *kobj);        //返回name

           int                 (*uevent)(struct kset *kset, struct kobject *kobj,         //uevent函数

                        struct kobj_uevent_env *env);

    };

     

    struct      kobj_uevent_env {

           char       *envp[UEVENT_NUM_ENVP];         //buf中每一段字符串的开始地址

           int          envp_idx;                                          //有几个envp,或者说buf中有几段字符串

           char       buf[UEVENT_BUFFER_SIZE];          //缓存(可以保存好几段字符串)

           int          buflen;                                              //buf尾

    };

     

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

     

     

    int   kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char *envp_ext[])

    调用kset-> uevent_ops-> uevent()函数

     

    int   add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)

    将格式化信息保存进env->buf中,关于env结构体可参考kobject.c的文件分析开头

     

    int   kobject_action_type(const char *buf, size_t count,      enum kobject_action *type)

    查找buf属于哪一个action动作,属于的动作返回到type中

     

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    由于kref.c代码很少,所以就把这两个文件合在一起分析了

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //原子的操作refcount,将其设置为1

    void       kref_init(struct kref *kref)

    {

           atomic_set(&kref->refcount,1);

           smp_mb();

    }

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //计数加1

    void       kref_get(struct kref *kref)

    {

           atomic_inc(&kref->refcount);

           smp_mb__after_atomic_inc();

    }

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //计数减1,为0则调用release函数

    int   kref_put(struct kref *kref,    void (*release)(struct kref *kref))

    {

           if (atomic_dec_and_test(&kref->refcount)) {

                  release(kref);

                  return 1;

           }

           return 0;

    }

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //关于uevent,目前猜测他应该是和热插拔有关

    u64        uevent_seqnum;

    char       uevent_helper[UEVENT_HELPER_PATH_LEN] =           //256

           CONFIG_UEVENT_HELPER_PATH;        // "/sbin/hotplug",这个定义在autoconf中

     

    static      DEFINE_SPINLOCK(sequence_lock);

    static      struct sock     *uevent_sock;

     

    //这几个状态都是定义在kobject.h的枚举结构之中

    static const char     *kobject_actions[] = {

           [KOBJ_ADD] =                   "add",

           [KOBJ_REMOVE] =           "remove",

           [KOBJ_CHANGE] =            "change",

           [KOBJ_MOVE] =                "move",

           [KOBJ_ONLINE] =             "online",

           [KOBJ_OFFLINE] =            "offline",

    };

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    跳读一下,在分析kobject.c文件时,我们看得最多的是kobject_uevent和kobject_uevent_env函数,所以我们先来看看这两个函数是干什么用的。

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //这个基本没什么说的了,直接调用了env

    int   kobject_uevent(struct kobject *kobj,    enum kobject_action action)

    {

           return     kobject_uevent_env(kobj, action, NULL);

    }

    EXPORT_SYMBOL_GPL(kobject_uevent);

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //好长一个函数啊,为了方便理解,我们先从kobject.c中拿出一个调用实例来比较

    //在rename函数中有这样的调用:

    kobject_uevent_env(kobj, KOBJ_MOVE, envp);

    其中envp的第一个元素保存的是更名前的kobj路径,第二个元素为空

    sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);

    envp[0] = devpath_string;

    envp[1] = NULL;

     

    这个函数很长,但也是超级的绕,绕到最后,其实就一个核心操作:

    retval = uevent_ops->uevent(kset, kobj, env);

    其中kset为kobj的宿主kset, kobj的参数传入,而env则是一些字符串信息

    int   kobject_uevent_env(

           struct kobject                      *kobj,                  //操作obj

           enum kobject_action     action,                   //动作( KOBJ_MOVE )

           char                            *envp_ext[])          //这个信息也只是添加进env->buf

    {

           struct kobj_uevent_env *env;

           const char *action_string = kobject_actions[action];    //根据动作参数获取字符串"move"

           const char *devpath = NULL;

           const char *subsystem;

           struct kobject *top_kobj;

           struct kset *kset;

           struct kset_uevent_ops *uevent_ops;

           u64 seq;

           int i = 0;

           int retval = 0;

     

           //--------------------------------------------------------

           //这一块代码的功能是找到kobj的宿主kset,然后从中提取出热插拔的操作函数

           //--------------------------------------------------------

           //找到根kobj,或者关联上了kset宿主

           top_kobj = kobj;

           while (!top_kobj->kset && top_kobj->parent)

                  top_kobj = top_kobj->parent;

     

           //根obj没有关联kset,出错

           if (!top_kobj->kset) {

                  pr_debug("kobject attempted to send uevent without kset!\n");

                  return -EINVAL;

           }

     

           //获取宿主kset,并从kset中提取出热插拔操作的ops

           kset = top_kobj->kset;

           uevent_ops = kset->uevent_ops;

     

           //--------------------------------------------------------

           //如果ops的filter()和name()函数有指定,则先执行他们

           //--------------------------------------------------------

           //如果ops存在 且 filter函数(过滤函数)有设置,则执行该函数

           //filter的作用应该是看看kobj是否被kset过滤到

           if (uevent_ops && uevent_ops->filter)

                  if (!uevent_ops->filter(kset, kobj)) {

                         pr_debug("kobject filter function caused the event to drop!\n");

                         return 0;

                  }

     

           //给subsystem指定name,如果ops->name()函数有指定,则从该函数返回,否则就获取kset->kobj的name。

           if (uevent_ops && uevent_ops->name)

                  subsystem = uevent_ops->name(kset, kobj);

           else

                  subsystem = kobject_name(&kset->kobj);

     

           //name为空,出错返回

           if (!subsystem) {

                  pr_debug("unset subsystem caused the event to drop!\n");

                  return 0;

           }

     

           //--------------------------------------------------------

           //申请一块env结构体,并填充他的env->buf字符串信息

           //--------------------------------------------------------

           //申请一快env内存

           env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);

           if (!env)

                  return -ENOMEM;

     

           //获取kobj的完整路径

           devpath = kobject_get_path(kobj, GFP_KERNEL);

           if (!devpath) {

                  retval = -ENOENT;

                  goto exit;

           }

     

           //这里出现了一个新的函数,add_uevent_var,OK,我们先中断这里,跳到后面去先分析这个函数

           //分析完add_uevent_var函数后,发现这个函数只是将参数的字符串保存进env->buf中,所以这一串函数只是保存一些字符串信息

           retval = add_uevent_var(env, "ACTION=%s", action_string);    //动作名

           if (retval)

                  goto exit;

           retval = add_uevent_var(env, "DEVPATH=%s", devpath);         //kobj路径

           if (retval)

                  goto exit;

           retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem); //subsys名

           if (retval)

                  goto exit;

     

           //如果参数三不为空,再保存参数三的字符串信息

           if (envp_ext) {

                  for (i = 0; envp_ext[i]; i++) {

                         retval = add_uevent_var(env, envp_ext[i]);

                         if (retval)

                                goto exit;

                  }

           }

           //--------------------------------------------------------

     

           //最后执行ops->uevent函数

           //绕了个大圈,最后却又调用了ops中指定的uevent

           if (uevent_ops && uevent_ops->uevent) {

                  retval = uevent_ops->uevent(kset, kobj, env);

                  if (retval) {

                         pr_debug ("%s - uevent() returned %d\n",

                                  __FUNCTION__, retval);

                         goto exit;

                  }

           }

     

           //将全局变量uevent_seqnum加1

           spin_lock(&sequence_lock);

           seq = ++uevent_seqnum;

           spin_unlock(&sequence_lock);

           retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);

           if (retval)

                  goto exit;

     

           //帮助信息,uevent_helper在申明时就已经给了一个默认的路径

           //这一块的代码实际和这个函数的关联不是很大了,所以可以不用理会

           if (uevent_helper[0]) {

                  char *argv [3];

     

                  argv [0] = uevent_helper;             // "/sbin/hotplug"

                  argv [1] = (char *)subsystem;              // kset的name

                  argv [2] = NULL;

                  retval = add_uevent_var(env, "HOME=/");

                  if (retval)

                         goto exit;

                  retval = add_uevent_var(env, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");

                  if (retval)

                         goto exit;

     

                  //让内核空间的驱动程序启用用户空间的若干应用程序,这个函数的简介可参考这个网址:http://linux.chinaunix.net/techdoc/beginner/2009/05/05/1110318.shtml

                  call_usermodehelper (argv[0], argv, env->envp, UMH_WAIT_EXEC);

           }

     

    exit:

           kfree(devpath);             //释放kobj路径

           kfree(env);                   //释放env

           return retval;

    }

    EXPORT_SYMBOL_GPL(kobject_uevent_env);

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //直接从上面抓他的一个引用来说问题:

    retval = add_uevent_var(env, "ACTION=%s", action_string);

    //分析完这个函数后,发现这个函数只是将format中的字符保存进env->buf中

    int   add_uevent_var(

           struct kobj_uevent_env *env,

           const char *format, ...)

    {

           va_list args;           //获取格式化列表的参数

           int len;

     

           //idx大于等于envp指针数组的大小,出错返回

           if (env->envp_idx >= ARRAY_SIZE(env->envp)) {

                  printk(KERN_ERR "add_uevent_var: too many keys\n");

                  WARN_ON(1);

                  return -ENOMEM;

           }

     

           //将格式化字符打印进env->buf中,

           //开始地址由env->buflen指定

           //最大长度由env->buf的大小 减去 env->buflen开始长度限制,以免越界

           va_start(args, format);

           len = vsnprintf(&env->buf[env->buflen],

                         sizeof(env->buf) - env->buflen,

                         format, args);

           va_end(args);

     

           //实际操作的长度在buf中越界了(实际是不可能的),出错返回

           if (len >= (sizeof(env->buf) - env->buflen)) {

                  printk(KERN_ERR "add_uevent_var: buffer size too small\n");

                  WARN_ON(1);

                  return -ENOMEM;

           }

     

           //记录本段字符串的开始地址

           env->envp[env->envp_idx++] = &env->buf[env->buflen];

           env->buflen += len + 1;

           return 0;

    }

    EXPORT_SYMBOL_GPL(add_uevent_var);

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //根据输入的buf查找该buf属于哪一个action命令

    int   kobject_action_type(

           const char      *buf,                    //要处理的字符串

           size_t            count,                   //要处理的字符串的长度

           enum kobject_action     *type)     //返回action类型

    {

           enum kobject_action action;

           int ret = -EINVAL;

     

           //从buf中剔除最后一个回车换行字符

           if (count && buf[count-1] == '\n')

                  count--;

     

           if (!count)

                  goto out;

     

           for (action = 0; action < ARRAY_SIZE(kobject_actions); action++) {

                  if (strncmp(kobject_actions[action], buf, count) != 0) //字符串不相等

                         continue;

     

                  //长度不相等,以免将“a”,“ab”两个误匹配

                  if (kobject_actions[action][count] != '\0')           

                         continue;

          

                  //找到匹配的字符串

                  *type = action;

                  ret = 0;

                  break;

           }

    out:

           return ret;

    }

     

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    //创建一个sock,准备发送信息到网络上

    static int __init      kobject_uevent_init(void)

    {

           uevent_sock = netlink_kernel_create(&init_net, NETLINK_KOBJECT_UEVENT,

                                           1, NULL, NULL, THIS_MODULE);

           if (!uevent_sock) {

                  printk(KERN_ERR

                         "kobject_uevent: unable to create netlink socket!\n");

                  return -ENODEV;

           }

     

           return 0;

    }

     

    postcore_initcall(kobject_uevent_init);         //这个函数放置在指定区域,初始化执行



        
    [3] [Arduino 课程] BareMinimum-从零开始
        来源: 互联网  发布时间: 2014-02-18
    [Arduino 教程] BareMinimum-从零开始
    原文:http://arduino.cc/en/Tutorial/BareMinimum
    译文:http://blog.csdn.net/qffj/article/details/8184332
    从最简单的代码开始

    这个例子包括Arduino所需的最少的代码:setup() 方法和loop() 方法.

    硬件需求
    • Arduino 开发板

    电路

    这个例子只需要一个Arduino 开发板。

    上图是用 Fritzing 制作. 更多的电路样例请看 Fritzing 项目主页

    编码

    当 sketch 开始时setup() 函数被调用. 用它来初始化变量、引脚模式、引用库文件等等。setup函数只会在每次上电或重置时运行一次。

    建立了setup() 函数以后,loop() 函数名副其实地开始了循环,你的程序在它运行的时候可以改变和响应。loop()中的代码用来在你的sketch中积极地控制Arduino 板。


    以下代码实际上并不做任何事,不过当你开始你自己的sketch时,它的结构很适合拷贝粘贴。这里也示例了如何加注释。


    编译器会忽略以2条斜线开始的行,所以你可以在后面写任何东西。给代码加注释能够帮助你自己和他人理解程序是如何逐步运行的。

    void setup() {
      // 设置代码,只运行一次

    }

    void loop() {
      // 循环运行的主要代码 
      
    }
    [取得代码]

    参见:
    • setup() 参考
    • loop() 参考

    • BareMinimum: 开始一个Arduino sketch的最简配置.
    • Blink: 开关 LED灯 .
    • DigitalReadSerial: 读取并打印开关状态到 Arduino 串口监视器.
    • AnalogReadSerial: 读取并打印电位器的状态到 Arduino  串口监视器.
    • Fade: 用模拟量输出来赋予 LED淡出效果.
    • ReadAnalogVoltage : 读取模拟输入并打印电压到串口监视器

        
    最新技术文章:
    ▪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详解
    ▪Android实现Back功能代码片段总结
    ▪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