首页 文章 精选 留言 我的

精选列表

搜索[移动app],共10000篇文章
优秀的个人博客,低调大师

UINavigationController 自定义转场动画(模仿淘宝App跳转)

制作目的 想要自定义系统转场动画速度 放弃不顺畅的 NavigationBar 隐藏消失 干脆直接干掉每个页面的 NavigationBar,在使用 UINavigationController 管理的同时,每个页面的 NavigationBar 都使用自定义的 UIView, 这样既定制程度高又可以在不需要 NavigationBar 的页面无缝对接,包括一些之前 NavigationBar 动画也可以更轻松的利用自定义的 UIView 的适配动画来更灵活的实现 实现功能 可以设置一个自己认为舒服的速度进行转场动画(该动画模仿系统转场动画效果,如果需要其他转场动画可以替换我的 LGFTransition 类,或者修改 LGFTransition 类的代码) 这个动画速度同时也舒服的作用到边缘手势拖动 POP 返回上 使用方式 pod 'LGFTransition' 或者 LGFTransition 接着在 AppDelegate 中导入头文件 UINavigationController+LGFAnimatedTransition.h #import "UINavigationController+LGFAnimatedTransition.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 在这里配置是否使用自定义转场动画 // Configure whether to use a custom transition animation here [UINavigationController lgf_AnimatedTransitionIsUse:YES]; //[UINavigationController lgf_AnimatedTransitionIsUse:YES transitionDuration:1.0]; return YES; } 在 didFinishLaunchingWithOptions 方法中调用 UINavigationController 由分类添加的新方法 lgf_AnimatedTransitionIsUse 传 NO 或不掉用该方法 使用系统效果, 调用该方法并传 YES 启用本效果 transitionDuration 动画想要执行的时间,默认 0.5 秒 Demo 里还添加了一个可以让普通按钮变成pop返回按钮的 UIButton 父类 自定义 NavigationBar 上的 UIButton 直接继承 LGFNavigationBackButton 就可以有pop返回的功能了 效果展示

优秀的个人博客,低调大师

iOS 判断App是否第一次启动

#defineLAST_RUN_VERSION_KEY@"last_run_version_of_application" -(BOOL)isFirstLoad{ NSString*currentVersion=[[[NSBundlemainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"]; NSUserDefaults*defaults=[NSUserDefaultsstandardUserDefaults]; NSString*lastRunVersion=[defaultsobjectForKey:LAST_RUN_VERSION_KEY]; if(!lastRunVersion){ [defaultssetObject:currentVersionforKey:LAST_RUN_VERSION_KEY]; returnYES; } elseif(![lastRunVersionisEqualToString:currentVersion]){ [defaultssetObject:currentVersionforKey:LAST_RUN_VERSION_KEY]; returnYES; } returnNO; } 本文转自 卓行天下 51CTO博客,原文链接:http://blog.51cto.com/9951038/1958145,如需转载请自行联系原作者

优秀的个人博客,低调大师

[Android Memory] App调试内存泄露之Context篇(上)

转载自:http://www.cnblogs.com/qianxudetianxia/p/3645106.html Context作为最基本的上下文,承载着Activity,Service等最基本组件。当有对象引用到Activity,并不能被回收释放,必将造成大范围的对象无法被回收释放,进而造成内存泄漏。 下面针对一些常用场景逐一分析。 1. CallBack对象的引用 先看一段代码: @Override protectedvoid onCreate(Bundle state){ super.onCreate(state); TextView label =new TextView(this); label.setText("Leaks are bad"); setContentView(label); } 大家看看有什么问题吗? 没问题是吧,继续看: private static Drawable sBackground; @Override protected void onCreate(Bundle state){ super.onCreate(state); TextView label =new TextView(this); label.setText("Leaks are bad"); if(sBackground ==null){ sBackground = getDrawable(R.drawable.large_bitmap); } label.setBackgroundDrawable(sBackground); setContentView(label); } 有问题吗? 哈哈,先Hold住一下,先来说一下android各版本发布的历史: /* 2.2 2010-3-20,Froyo 2.3 2010-12-6, Gingerbread 3.0 2011-2-22, Honeycomb 4.0 2011-10-11 Ice Cream Sandwich */ 了解源码的历史,是很有益于我们分析android代码的。 好,开始分析代码。 首先,查看setBackgroundDrawable(Drawable background)方法源码里面有一行代码引起我们的注意: public void setBackgroundDrawable(Drawable background) { // ... ... background.setCallback(this); // ... ... } 所以sBackground对view保持了一个引用,view对activity保持了一个引用。 当退出当前Activity时,当前Activity本该释放,但是因为sBackground是静态变量,它的生命周期并没有结束,而sBackground间接保持对Activity的引用,导致当前Activity对象不能被释放,进而导致内存泄露。 所以结论是:有内存泄露! 这是Android官方文档的例子:http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html 到此结束了吗? 我发现网上太多直接抄或者间接抄这篇文章,一搜一大片,并且吸引了大量的Android初学者不断的转载学习。 但是经过本人深入分析Drawable源码,事情发生了一些变化。 Android官方文档的这篇文章是写于2009年1月的,当时的Android Source至少是Froyo之前的。 Froyo的Drawable的setCallback()方法的实现是这样的: public final void setCallback(Callback cb) { mCallback = cb; } 在GingerBread的代码还是如此的。 但是当进入HoneyComb,也就是3.0之后的代码我们发现Drawable的setCallback()方法的实现变成了: public final void setCallback(Callback cb) { mCallback = new WeakReference<Callback>(cb); } 也就是说3.0之后,Drawable使用了软引用,把这个泄露的例子问题修复了。(至于软引用怎么解决了以后有机会再分析吧) 所以最终结论是,在android3.0之前是有内存泄露,在3.0之后无内存泄露! 如果认真比较代码的话,Android3.0前后的代码改进了大量类似代码,前面的Cursor篇里的例子也是在3.0之后修复了。 从这个例子中,我们很好的发现了内存是怎么通过回调泄露的,同时通过官方代码的update也了解到了怎么修复类似的内存泄露。 2. System Service对象 通过各种系统服务,我们能够做一些系统设计好的底层功能: //ContextImpl.java @Override public Object getSystemService(String name) { ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); return fetcher == null ? null : fetcher.getService(this); } static { registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() { public Object getService(ContextImpl ctx) { return AccessibilityManager.getInstance(ctx); }}); registerService(CAPTIONING_SERVICE, new ServiceFetcher() { public Object getService(ContextImpl ctx) { return new CaptioningManager(ctx); }}); registerService(ACCOUNT_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(ACCOUNT_SERVICE); IAccountManager service = IAccountManager.Stub.asInterface(b); return new AccountManager(ctx, service); }}); // ... ... } 这些其实就是定义在Context里的,按理说这些都是系统的服务,应该都没问题,但是代码到了各家厂商一改,事情发生了一些变化。 一些厂商定义的服务,或者厂商自己修改了一些新的代码导致系统服务引用了Context对象不能及时释放,我曾经碰到过Wifi,Storage服务都有内存泄露。 我们改不了这些系统级应用,我们只能修改自己的应用。 解决方案就是:使用ApplicationContext代替Context。 举个例子吧: // For example mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE); 改成: mStorageManager = (StorageManager) getApplicationContext().getSystemService(Context.STORAGE_SERVICE); 3. Handler对象 先看一段代码: public class MainActivity extends QActivity { // lint tip: This Handler class should be static or leaks might occur class MyHandler extends Handler { ... ... } } Handler泄露的关键点有两个: 1). 内部类 2). 生命周期和Activity不一定一致 第一点,Handler使用的比较多,经常需要在Activity中创建内部类,所以这种场景还是很多的。 内部类持有外部类Activity的引用,当Handler对象有Message在排队,则无法释放,进而导致Activity对象不能释放。 如果是声明为static,则该内部类不持有外部Acitivity的引用,则不会阻塞Activity对象的释放。 如果声明为static后,可在其内部声明一个弱引用(WeakReference)引用外部类。 public class MainActivity extends Activity { private CustomHandler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mHandler = new CustomHandler(this); } static class CustomHandlerextends Handler { // 内部声明一个弱引用,引用外部类 private WeakReference<MainActivity > activityWeakReference; public MyHandler(MyActivity activity) { activityWeakReference= new WeakReference<MainActivity >(activity); } // ... ... } } 第二点,其实不单指内部类,而是所有Handler对象,如何解决上面说的Handler对象有Message在排队,而不阻塞Activity对象释放? 解决方案也很简单,在Activity onStop或者onDestroy的时候,取消掉该Handler对象的Message和Runnable。 通过查看Handler的API,它有几个方法:removeCallbacks(Runnabler)和removeMessages(int what)等。 // 一切都是为了不要让mHandler拖泥带水 @Override public void onDestroy() { mHandler.removeMessages(MESSAGE_1); mHandler.removeMessages(MESSAGE_2); mHandler.removeMessages(MESSAGE_3); mHandler.removeMessages(MESSAGE_4); // ... ... mHandler.removeCallbacks(mRunnable); // ... ... } 上面的代码太长?好吧,出大招: @Override public void onDestroy() { // If null, all callbacks and messages will be removed. mHandler.removeCallbacksAndMessages(null); } 有人会问,当Activity退出的时候,我还有好多事情要做,怎么办?我想一定有办法的,比如用Service等等. 4. Thread对象 同Handler对象可能造成内存泄露的原理一样,Thread的生命周期不一定是和Activity生命周期一致。 而且因为Thread主要面向多任务,往往会造成大量的Thread实例。 据此,Thread对象有2个需要注意的泄漏点: 1). 创建过多的Thread对象 2). Thread对象在Activity退出后依然在后台执行 解决方案是: 1).使用ThreadPoolExecutor,在同时做很多异步事件的时候是很常用的,这个不细说。 2).当Activity退出的时候,退出Thread。 第一点,例子太多,建议大家参考一下afinal中AsyncTask的实现学习。 第二点,如何正常退出Thread,我在之前的博文中也提到过。示例代码如下: // ref http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html private volatile Thread blinker; public void stop() { blinker = null; } public void run() { Thread thisThread = Thread.currentThread(); while (blinker == thisThread) { try { thisThread.sleep(interval); } catch (InterruptedException e){ } repaint(); } } 有人会问,当Activity退出的时候,我还有好多事情要做,怎么办?请看上面Handler的分析最后一行。 (未完待续) 分类: Android Memory 本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/p/3755894.html如需转载请自行联系原作者 demoblog

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册