当前位置:  编程技术>移动开发
本页文章导读:
    ▪处置home按键清空Activity所在的Task堆栈        处理home按键清空Activity所在的Task堆栈长虹厂商反馈的问题:   当通过intent外部调起的详情页面,按home键回到launcher,再次通过intent调起播放页面,按back键返回,会发现上次调用过的详情页.........
    ▪ CALayer的容易使用        CALayer的简单使用 原文地址:http://www.raywenderlich.com/2502/calayers-tutorial-for-ios-introduction-to-calayers-tutorial 如果你已经在iPhone上做过开发,你可能对UIView和它的子类-Button,text,slider等,非常熟悉。 但.........
    ▪ Atomthreads关于STM8S低功耗的考虑       Atomthreads关于STM8S低功耗的思考Atomthreads像众多操作系统一样,在没有任务调度是会调用idle。 static void atomIdleThread (uint32_t param) { /* Compiler warning */ param = param; /* Loop forever */ while (.........

[1]处置home按键清空Activity所在的Task堆栈
    来源: 互联网  发布时间: 2014-02-18
处理home按键清空Activity所在的Task堆栈
长虹厂商反馈的问题:

  当通过intent外部调起的详情页面,按home键回到launcher,再次通过intent调起播放页面,按back键返回,会发现上次调用过的详情页。

  想了想,这个问题其实是Activity和Task堆栈的问题。正好回顾一下task,launch mode这几个概念,高手直接略过。

  Task是执行用户工作,与用户交互的一组Activity的集合。 当用户在应用启动器中触击一个应用的图标,系统会内存中寻找有没有该应用打开过的堆栈

  如果有,这个应用就会回到前台。如果没有这个应用的任务存在,那么创建一个新的 task,这个应用的 “main” Activity打开,并且作为这个 task栈的根 activity。Activity被安排到同一个栈 (back stack)中,其中的 activity按顺序的打开的。

  在同一个应用中,打开Activity和按back按键,Activity在堆栈中的变化过程如下:

  一般情况下,我们不用担心Activity怎么和task关联,不需要关系Activity如何存在于stack中。但是比如我们现在遇到的问题,厂商明显是想中断这种常态行为,希望按home键离开应用的task时,应用自动清除task内的所有activity。

  这个时候,我们就需要使用launch mode和Intent flag来改变activity与task的这种默认行为。

  关于launch mode和intent flag不在做详细的解释,参考这里,讲解的很细致。

  Activity的四种加载模式 http://marshal.easymorse.com/archives/2950

  android之intent的Flag详解 http://hi.baidu.com/jieme1989/item/6e5f41d3f65be848ddf9beb9

  画一个流程图,复现厂商说的问题

既然是要求按home按键,清空堆栈。可以有两种做法。

 1.监听Home按键,当用户按下Home按键时,结束自己的进程。

这里有两个问题:

第一个就是Home按键的捕获,一般是捕获不到的。

:可以使用一个线程去监视系统日志(有点笨,不过还算有效)

第二个是如果是android厂商的话,一般都会修改Framework,可以让他们在home键按下的时候,发一个广播出来。App

可以根据此广播,处理相应的逻辑。

  2.可以使用launch Mode配合Intent Flag完成

第三方调起应用时,可以在getIntent()中,加入Intent.FLAG_ACTIVITY_CLEAR_TASK ,同时调起的Activity的launch mode设置为singleTask

也就是第三方调起的每个页面,在启动前都会对Task进行清空,从而避免上述问题。



  原文链接:http://www.67tgb.com/?p=628

  转载注明:望月听涛


    
[2] CALayer的容易使用
    来源: 互联网  发布时间: 2014-02-18
CALayer的简单使用

原文地址:http://www.raywenderlich.com/2502/calayers-tutorial-for-ios-introduction-to-calayers-tutorial


如果你已经在iPhone上做过开发,你可能对UIView和它的子类-Button,text,slider等,非常熟悉。

但你可能不了解UIView是建立在CALayers之上的,至少我曾经有段时间不知道。
了解CALayers是有用的,因为你可以使用它们轻松地去创造一些纯视觉效果,它们对理解使用将在未来教程中讨论的Core Animation也很重要。
在CALayers的教程中,你将通过做创造一个层并实验它的效果的简单APP去学习基本的层的使用,在这个过程中,你将学到层是什么,一些能设置的纯属性和如何将图像和自定义内容放入层里。

这个层的教程假设你基本熟悉iPhone编程,如果你是新手,可以从如何创建一个简单的iPhone App开始。
让我们开始吧
什么是层?
层是表现一个在屏幕上的包含可视内容的矩形的简单类。
“等一下”,你可能说,“这是UIView的定义”,是这样的,但这儿有个把戏:每一个UIView包含一个用于绘制的根层,你可以使用下面的代码访问这个自动创造的层:(CALayer是UIView的根基)
CALayer *myLayer = myView.layer;
CALayer类包含了很多可设置的影响外观显示的属性,例如:
层的尺寸和位置
层的背景颜色
层的内容(图像或者使用Core Graphics绘制的)
是否是圆角层
在层的边缘应用边框
更多内容
你可以使用这些属性去创造一些效果,例如你想拿一副图片,放在白色的边框,应用一个阴影效果,使其更为逼真,而不是拿出Photoshop或写一堆Core Graphicsdaima代码,你可以使用层的代码。
另外层的属性,多数是可以动画的,例如,你可以开始用圆角图片,点击按钮,有个动画效果,圆角变回直角,使用起来是非常方便简单的。
你可以直接使用层类,或者你可以使用一个它的子类,例如CAGradientLayer, CATextLayer, CAShapeLayer,和其他。UIView默认的层类是CALayer类,这个是教程的重点。
开始
这儿去了解层的使用的最好方法是自己动手,所以启动Xcode,选择File\New Project,选择 iOS\Application\View-Based Application,点"Choose",起名工程"Layer
Fun",点保存(就是创建个测试Layer的工程)。
添加QuzatCore,做下列改动到LayerFunViewController.m:
// Import QuartzCore.h at the top of the file
#import <QuartzCore/QuartzCore.h>
 
// Uncomment viewDidLoad and add the following lines
self.view.layer.backgroundColor = [UIColor orangeColor].CGColor;
self.view.layer.cornerRadius = 20.0; 
self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);


让我们一步一步回顾这些新东西
为了得到view的层,你可以使用self.view.layer,记住,你可以使用self.view获得view controller 的根视图,你一旦得到视图,你可以使用view.layer获得默认的层(自动创建的),默认层是一个CALayer的类(不是子类)。
下一步你设置层的背景色为橙色,注意背景色属性实际是CGColor类型,但可以使用CGColor属性从UIColor到CGColor转换。
下一步你设置圆角的弧度,设置的这个值是制造圆角的圆的半径,20是一个漂亮的圆角边缘。
最终,你使用CGRectInset的功能,收缩一点frame,方便看到效果。CGRectInset函数收缩X和Y的坐标,返回一个新的Frame。
编译执行你的代码,你可以在屏幕中央看到一个圆角橙色矩形。

层和子层
就像UIView可以有自视图,CALayers可以也可以用子层,你可以使用下面的代码创建一个新的层:
CALayer *sublayer = [CALayer layer];
一旦你拥有一个层,你可以在上面设置任何你想要的属性,但是记住这儿有一个属性你一定要设置:它是frame(或者bounds/ position)。毕竟,层需要去知道它有多大(在什么位置),才能画出自己。当你完成了,你可以把新的层当作子层添加到另一个层中,通过下面的代码:
[myLayer addSublayer:sublayer];
好了,现在试着自己添加一个简单的子层到view的层中,添加下面的代码在viewDidLoad函数内之前添加代码的后面:
CALayer *sublayer = [CALayer layer];
sublayer.backgroundColor = [UIColor blueColor].CGColor;
sublayer.shadowOffset = CGSizeMake(0, 3);
sublayer.shadowRadius = 5.0;
sublayer.shadowColor = [UIColor blackColor].CGColor;
sublayer.shadowOpacity = 0.8;
sublayer.frame = CGRectMake(30, 30, 128, 192); 
[self.view.layer addSublayer:sublayer];

这创建了一个新的层,并且设置了一些属性,包括一些之前没设置过的阴影属性,你可以看到在层上设置阴影是多么简单,通过这样,可以用一点工作量完成令人惊奇的效果。(就是简单、方便、有效果)
在设置了这些属性,需要设置层的frame并且把它加到view的层中,记住这些坐标是相对于父层的frame(父层坐标体系的坐标)如果父层位于(20,20),子层设置偏移(30,30),子层在屏幕的位置将会是(50,50).
编译执行你的代码,你将看到一个蓝色子层在屏幕上。


设置层的图像内容
CALayers可以包含更多的内容除了纯颜色,它非常容易包含图片内容,例如:
先将一张名为“BattleMapSplashScreen.jpg”的图片包含进项目
然后添加以下代码:
sublayer.contents = (id) [UIImage imageNamed:@"BattleMapSplashScreen.jpg"].CGImage;
sublayer.borderColor = [UIColor blackColor].CGColor; 
sublayer.borderWidth = 2.0;


这里设置了内容为图片的层,并且使用边界的颜色和宽度设置了一圈黑色的边界,演示了它如何工作。
编译执行你的代码,你可以看到蓝色层的内容被图片替换调了。

圆角半径和图片内容的注意点
现在你可能想通过cornerRadius把图片也设置成圆角效果。
然而问题超过了咱们之前学的范围,如果你在层上设置了图片内容,图像将仍然画出圆角的边界(该属性起不了作用),你可以通过设置子层的masksToBounds为Yes,但如果你这样做,阴影效果将不会出现因为他们被盖掉了。

我找到一个创造两个层的方法,在外的层是有边框和阴影带颜色的层,里面的层包含圆角图像和设置mask,这样在外的层绘制阴影,在里的层包含图像。

试着使用下面的替换创建子层的代码:
CALayer *sublayer = [CALayer layer];
sublayer.backgroundColor = [UIColor blueColor].CGColor;
sublayer.shadowOffset = CGSizeMake(0, 3);
sublayer.shadowRadius = 5.0;
sublayer.shadowColor = [UIColor blackColor].CGColor;
sublayer.shadowOpacity = 0.8;
sublayer.frame = CGRectMake(30, 30, 128, 192);
sublayer.borderColor = [UIColor blackColor].CGColor;
sublayer.borderWidth = 2.0;
sublayer.cornerRadius = 10.0;
[self.view.layer addSublayer:sublayer];
 
CALayer *imageLayer = [CALayer layer];
imageLayer.frame = sublayer.bounds;
imageLayer.cornerRadius = 10.0;
imageLayer.contents = (id) [UIImage imageNamed:@"BattleMapSplashScreen.jpg"].CGImage;
imageLayer.masksToBounds = YES; 
[sublayer addSublayer:imageLayer];
编译运行代码,现在你的图像将有圆角

层和自定义绘画内容
如果你想使用Core Graphics替代图片绘制自定义的层,也是很容易的。
方法是你设置一个类作为层的代理对象,这个类实现名为drawLayer:inContext的方法,里面包含你想绘制内容的Core Graphics代码。
让我们试着添加一个新的层,在里面画一个图案,你把层的代理指向view controller的对象,实现drawLayer:inContext的方法去画图案。
在你的viewDidLoad添加以下代码建立一个新层:
CALayer *customDrawn = [CALayer layer];
customDrawn.delegate = self;
customDrawn.backgroundColor = [UIColor greenColor].CGColor;
customDrawn.frame = CGRectMake(30, 250, 128, 40);
customDrawn.shadowOffset = CGSizeMake(0, 3);
customDrawn.shadowRadius = 5.0;
customDrawn.shadowColor = [UIColor blackColor].CGColor;
customDrawn.shadowOpacity = 0.8;
customDrawn.cornerRadius = 10.0;
customDrawn.borderColor = [UIColor blackColor].CGColor;
customDrawn.borderWidth = 2.0;
customDrawn.masksToBounds = YES;
[self.view.layer addSublayer:customDrawn]; 
[customDrawn setNeedsDisplay];

这里的代码,大多数之前都出现过,就有两点是新的:
1 第一 把层的委托设置给self,这以为这个对象(self)将需要实现 drawLayer:inContext去绘制层的内容。
2 在添加层后,需要通过调用setNeedsDisplay通知层去刷新自己(并调用drawLayer:inContext),如果你忘记调用这个,drawLayer:inContext将不会被调用,图案将不出现。
接下来添加代码去实现drawLayer:inContext,如下:
void MyDrawColoredPattern (void *info, CGContextRef context) {
 
    CGColorRef dotColor = [UIColor colorWithHue:0 saturation:0 brightness:0.07 alpha:1.0].CGColor;
    CGColorRef shadowColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.1].CGColor;
 
    CGContextSetFillColorWithColor(context, dotColor);
    CGContextSetShadowWithColor(context, CGSizeMake(0, 1), 1, shadowColor);
 
    CGContextAddArc(context, 3, 3, 4, 0, radians(360), 0);
    CGContextFillPath(context);
 
    CGContextAddArc(context, 16, 16, 4, 0, radians(360), 0);
    CGContextFillPath(context);
 
}
 
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context {
 
    CGColorRef bgColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor;
    CGContextSetFillColorWithColor(context, bgColor);
    CGContextFillRect(context, layer.bounds);
 
    static const CGPatternCallbacks callbacks = { 0, &MyDrawColoredPattern, NULL };
 
    CGContextSaveGState(context);
    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
    CGContextSetFillColorSpace(context, patternSpace);
    CGColorSpaceRelease(patternSpace);
 
    CGPatternRef pattern = CGPatternCreate(NULL,
                                           layer.bounds,
                                           CGAffineTransformIdentity,
                                           24,
                                           24,
                                           kCGPatternTilingConstantSpacing,
                                           true,
                                           &callbacks);
    CGFloat alpha = 1.0;
    CGContextSetFillPattern(context, pattern, &alpha);
    CGPatternRelease(pattern);
    CGContextFillRect(context, layer.bounds);
    CGContextRestoreGState(context); 
}


就是这样,运行代码,你将在图片下面看到一个蓝色的图案

将来
下载源代码点击,





    
[3] Atomthreads关于STM8S低功耗的考虑
    来源: 互联网  发布时间: 2014-02-18
Atomthreads关于STM8S低功耗的思考

Atomthreads像众多操作系统一样,在没有任务调度是会调用idle。

static void atomIdleThread (uint32_t param)
{
    /* Compiler warning  */
    param = param;

    /* Loop forever */
    while (1)
    {
        /** \todo Provide user idle hooks*/
    }
}

atomthreads中atomIdleThread()是以线程的形式存在,也就是最低优先级线程。作者默认没有填写这个函数。

uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size)
{
    uint8_t status;

    /* Initialise data */
    curr_tcb = NULL;
    tcbReadyQ = NULL;
    atomOSStarted = FALSE;

    /* Create the idle thread */
    status = atomThreadCreate(&idle_tcb,
                 IDLE_THREAD_PRIORITY,
                 atomIdleThread,
                 0,
                 idle_thread_stack_top,
                 idle_thread_stack_size);

    /* Return status */
    return (status);

}
针对STM8我们最自然想到的是在其中加一个wfi,STM8进入wfi模式几乎不会影响任何外设的运行。以STM8S105K4为例,其进入该模式的典型电流是1.8mA。这个电流,用一节2000mA手机供电,理论上也最多能坚持46天,才一个月多点。这个记录太差了。

STM8还有一个HALT模式,这是该芯片的最低功耗模式,电流是uA级别。但是该模式有诸多限制,进入该模式系统几乎所有的clock都停止,你的timer,adc,uart等等全部停止,除了AWU。

atomthreads如果你在idle直接进入HALT,因为基本只有外部中断可以唤醒退出这个模式,当系统醒来了,请你想想,你的系统心跳还准么?你的应用线程如果使用了定时器,本来希望1秒钟后调用某个CALLBACK,结果HALT睡了5分钟,那还是定时器API本身参数的意义么?

对datasheet熟悉的读者可能,可能立刻想到了AWU,似乎可以解决这个问题。在idle进入HALT前,把还能睡的时间填入AWU,这样系统就可以在制定的时间被唤醒。粗略的一看,还以为问题解决了。


暂时不谈AWU的时间不是任意值都可以接受的,是一个非常不准确的唤醒时钟。

我给你举个其他例子,如果idle进入HALT前,系统还可以睡20分钟,我觉的一个设计优良的低功耗系统,应用层让系统有睡20分钟的可能性是很起码的。不幸的是,在5分钟的时候,一个外部中断进来了,系统很自然退出HALT。我想问你,从系统的角度看,系统之前睡了多久。不要告诉玩我是5分钟,大哥,那是我假设的,我问得是,从系统的角度。睡了多久?AWU这个唯一在运行的模块,上面是没有时间让你读的,你完全无法得知刚才睡了多久。

其实上面的这个理念不是我创造的,在linux中早就有了,它叫variable tick timer,什么意思?通常我们的心跳时钟,是有规律的触发中断,比如10ms一次,这导致系统最多能安静10ms,想多睡会儿?没门!10ms后中断就来了。这种设计对低功耗是不利的。后来就有大牛,引入了variable tick timer,这里tick timer就是我们上面一直说的心跳时钟。variable就是可变的罗!表面意思就是我们的心脏可以走走停停,这样想已经不符合人类的自然规律,所以也确实不能再叫heart beattimer。当系统醒的时候,是有规律的跳动,当系统睡眠的时候, timer就停跳。其实就是上面想实现的东西。


    
最新技术文章:
▪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