当前位置:  编程技术>移动开发
本页文章导读:
    ▪wp8下压缩纹路的使用(dds)        wp8下压缩纹理的使用(dds)        个人认为,既然手机设备支持wp8支持dx11,那么dds的压缩纹理必然是被支持的。不过依然不保证完全如此。希望看此文章的同仁留意。         微软wp系统.........
    ▪ ListView最终优化方法,绝对流畅        ListView终极优化方法,绝对流畅     listview可以说是Android开发中最常见的UI控件了,listview能够以列表的方式显示大量同类的数据,这样问题就产生了,既然是大量数据,就会使用到很多布局.........
    ▪ 使用ASIHTTPRequest跟ASIDownloadCache实现本地缓存       使用ASIHTTPRequest和ASIDownloadCache实现本地缓存     NSURL *url = [NSURLURLWithString:@"http://pica.nipic.com/2007-12-12/20071212235955316_2.jpg"];  ASIFormDataRequest *request = [ASIFormDataRequestrequestWithURL:url];//创建数据.........

[1]wp8下压缩纹路的使用(dds)
    来源: 互联网  发布时间: 2014-02-18
wp8下压缩纹理的使用(dds)

        个人认为,既然手机设备支持wp8支持dx11,那么dds的压缩纹理必然是被支持的。不过依然不保证完全如此。希望看此文章的同仁留意。

        微软wp系统在内存管理上有一个不同于ios和android的地方,那就是给程序预先分配的内存是有限的。正常情况是150mb,通过设置一些标志可以允许180mb或者300mb。程序分配的内存超过限额就会分配失败抛出异常,即便这个时候手机剩余内存还剩七八百兆。所以买低端手机的劣势就是很多游戏不是没有,而是你看不到,因为那些游戏因为安全起见,申请了300mb的内存,那么只有512mb内存的手机可能就看不到这个应用了,即便它可以在这个手机上跑起来。

       反过来,对游戏开发而言,内存控制就变得更加重要了。 不过这里还是要吐槽一下,wp8使用native c++进行开发的话,没有任何途径可以获取内存使用情况进行分析。一没有工具,二没有系统api。 只能靠程序员给力些了。

      比如我的卡牌游戏,一开始分配内存可能达到200mb,那么就经常性的崩溃。后面使用dds的压缩纹理后,就没有出现崩溃情况了。理论上说dds跟pvrtc4一样都是4个字节表示一个像素,所以使用dds的游戏在wp8上面的运行内存情况应该跟使用pvrtc4在ios上面运行一样。

     首先说转换工具,我找了半天终于找到个靠谱的工具。Nvida Texture Tools,这个有工具有代码。不过默认情况下程序不识别png jpg图片,后面我重新用源代码编译了一份。

     之所以要使用这个工具而不是市面上大多数图片转换工具是因为dds图片的压缩纹理格式分很多种,常见的有dxt1 dxt3 dxt5,常用的是dxt3,dxt1色彩不足,而dxt5不是所有设备都支持,比如我的lumia920,使用dx api检测时就不支持dxt5。

     较新的cocos2d-x代码里面已经包含了s3tc压缩纹理的支持。dds的压缩纹理格式就是s3tc。读取纹理可以直接使用,而不需要特别写初始化代码了(比如 CreateDDSTextureFromFile就没有必要了)


    
[2] ListView最终优化方法,绝对流畅
    来源: 互联网  发布时间: 2014-02-18
ListView终极优化方法,绝对流畅
     listview可以说是Android开发中最常见的UI控件了,listview能够以列表的方式显示大量同类的数据,这样问题就产生了,既然是大量数据,就会使用到很多布局,给布局绑定数据,listview将占用大量资源还可能会产生卡顿现象。
     listview现在最常用也拥有很好的性能的优化方式是在Adapter中使用静态的ViewHolder,具体代码如下:
      Activity
     private TestAdapter mAdapter;

    private String[] mArrData;
    private TextView mTV;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mTV = (TextView) findViewById(R.id.tvShow);

        mArrData = new String[1000];
        for (int i = 0; i < 1000; i++) {
            mArrData[i] = "Google IO Adapter" + i;
        }
        mAdapter = new TestAdapter(this, mArrData);
        ((ListView) findViewById(android.R.id.list)).setAdapter(mAdapter);
    }
         Adapter
      private int count = 0;
    private long sum = 0L;

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // 开始计时
            long startTime = System.nanoTime();

            ViewHolder holder;
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.list_item_icon_text,
                        null);
                holder = new ViewHolder();
                holder.icon1 = (ImageView) convertView.findViewById(R.id.icon1);
                holder.text1 = (TextView) convertView.findViewById(R.id.text1);
                holder.icon2 = (ImageView) convertView.findViewById(R.id.icon2);
                holder.text2 = (TextView) convertView.findViewById(R.id.text2);
                convertView.setTag(holder);
            }
            else{
                holder = (ViewHolder)convertView.getTag();
            }
            holder.icon1.setImageResource(R.drawable.icon);
            holder.text1.setText(mData[position]);
            holder.icon2 .setImageResource(R.drawable.icon);
            holder.text2.setText(mData[position]);

            // 停止计时
            long endTime = System.nanoTime();
            // 计算耗时
            long val = (endTime - startTime) / 1000L;
            Log.e("Test", "Position:" + position + ":" + val);
            if (count < 100) {
                if (val < 1000L) {
                    sum += val;
                    count++;
                }
            } else
                mTV.setText(String.valueOf(sum / 100L));// 显示统计结果
            return convertView;
        }
    }

    static class ViewHolder {
        TextView text1;
        ImageView icon1;
        TextView text2;
        ImageView icon2;
    }

     在Adapter的代码中,在getView方法里首先判断convertView是否为空,若为空则加载相应布局,若不为空则直接使用该布局,这能够很有效的使用Android为listview提供的缓存机制:只加载一屏的布局,之后滑动出来的item使用的是之前已经加载的布局的缓存;
     而使用静态的ViewHoulder的目的则是节省了findViewById的时间。如果不使用ViewHolder,每次getView的时候都需要得到一次子布局,而这也是很耗时并且耗资源的;如果使用了ViewHolder作为子布局的缓存,使用View的setTag方法将缓存与每个item绑定,则也可以省去了findViewById的事件;而将ViewHolder设置为static的目的是指在初始化Adapter时初始化一次这个内部类,否则将会在每次创建Adapter时都要初始化一次,而这是没有必要的。

          上述方法能够解决大部分listview消耗资源以及卡顿的问题,但对于不同的需求的listview来说还会存在其他让listview卡顿的原因,比如listview的item每次加载时都需要获得图片并设置到imageview中,item加载时需要进行大量的计算,item里的TextView需要设置指定字体;这些耗时的操作都会让listview滑动起来很卡,带来不好的体验;
          这几天我一直在研究Android4.0+系统联系人的源码,因为我发现,系统联系人采用的也是listview布局,每一个item都有图片文字,而且使用了fastscroller模式,对联系人以首字母进行了分来,同时Adapter还实现了SectionIndexer接口,能够实现这种效果:
但是却一点都不卡,而我自己做的一个类似的界面,却十分卡顿,很影响用户体验;于是我找来了Android体统联系人的源码,自己建立起来了一个可以运行的程序,然后去研究它是如何实现这么流畅的listview的;
       经过研究我发现系统联系人的listview使用的是自定义的listview:PinnedHeaderListView 它的定义是这样的:
/**
 * A ListView that maintains a header pinned at the top of the list. The
 * pinned header can be pushed up and dissolved as needed.
 */ 
它给listview加了一个header即显示在联系人界面最上方贴着屏幕顶部的那部分,同时它继承自AutoScrollListView 而这个AutoScrollListView继承自listview,对listview进行了一些优化,让listview在互动到指定的item时更流畅;
       看到这里,于是我使用了这个AutoScrollListView ,但效果不是很明显,listview还是很卡;在系统联系人使用的listview中没有找到解决方法,我开始研究它的Adapter;研究Adapter发现,系统的Adapter进行了很多层的封装,完全淡化了geiView方法;使用了很多AsyncTask来加载不同的数据,然后使用了CursorLoader来将加载好的数据添加到Adapter里,同时还将图片的加载与数据的加载进行了分离,代码逻辑十分复杂;但通过这个我得出了一个结论:不要将任何的耗时操作放在listview的getView方法里。
         在系统联系人的这些Adapter里我发现getView方法中没有任何的耗时操作,在设置图片时图片已经得到,对列表按照字母进行的分类也已经分类好了,存放在一个内部类里;在得出这个结论之前我尝试过很多系统联系人中的代码,但都没有得到明显的效果,经过大量的测试我得出了这个结论,并且在测试中得到了验证。
        在我的项目中,listview的每一个item都有一个图片,和很多TextView,而且所有的TextView都要设置非系统的字体;Adapter使用的是ViewHolder优化,在getView中的代码已经很少了,但是还是卡;我的listview中的数据是一个对象的List,在对象里只存放了item需要展示的图片的资源ID,或者是图片的路径,需要通过一些操作才能获得图片,而这些操作其实是很耗时的;于是我将原来的对象进行了更改,将图片对象直接存放在item对应的对象中,然后再Adapter初始化的时候将这些对象初始化,虽然listview展示所需的时间稍微长了一点,但是结果是listview滑动流畅了很多;接着我又将从assets中获得字体TypeFace的操作放在了Adapter初始化的方法中,并且将字体通过静态的变量都存起来,然后再getView中只需为TextView设置一下taptface即可,不需要在从asset中获取字体所花费的时间;通过上面两步操作之后,我的listview一点都不卡了,十分流畅。
        综上,listview的优化其实就是去找getView中的耗时操作,然后提取出来,要么使用异步的方式为item的布局设置数据,要是实在需要同步,就只能在Adapter初始化时将数据准备好,然后再getView中只需绑定一下就行。


    
[3] 使用ASIHTTPRequest跟ASIDownloadCache实现本地缓存
    来源: 互联网  发布时间: 2014-02-18
使用ASIHTTPRequest和ASIDownloadCache实现本地缓存

 

  NSURL *url = [NSURLURLWithString:@"http://pica.nipic.com/2007-12-12/20071212235955316_2.jpg"];

 ASIFormDataRequest *request = [ASIFormDataRequestrequestWithURL:url];//创建数据请求对象

    [request setRequestMethod:@"GET"];

    [request setTimeOutSeconds:60];

//    [request setDelegate:self];//设置代理

    

  

   

//    设置缓存--

     ASIDownloadCache *cache = [[ASIDownloadCachealloc]init];//创建缓存对象

    NSString *cachePath = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents"]; //设置缓存目录,这里设置沙盒目录下的Documents目录作为缓存目录

    NSLog(@"cachepath:%@",cachePath);

    [cache setStoragePath:cachePath];

    cache.defaultCachePolicy =ASIOnlyLoadIfNotCachedCachePolicy; //设置缓存策略

    

    //每次请求会将上一次的请求缓存文件清除

    //    request.cacheStoragePolicy = ASICacheForSessionDurationCacheStoragePolicy;

    //持久缓存,一直保存在本地(是持久缓存,程序下次启动,缓存仍然还在)

    request.cacheStoragePolicy =ASICachePermanentlyCacheStoragePolicy;

    request.downloadCache = cache;

    

   

    

    [request startAsynchronous];//发送异步请求

    

    //设置网络请求完成后调用的block

    [request setCompletionBlock:^{

        

        //         NSLog(@"%@",request.responseHeaders);

        

        NSData *data = request.responseData;

        self.showImageView.image = [UIImageimageWithData:data];

        

        //---------------判断数据的来源:网络 or缓存------------------

        if (request.didUseCachedResponse) {

            NSLog(@"数据来自缓存");

        } else {

            NSLog(@"数据来自网络");

        }

        

    }];

    

    //请求失败调用的block

    [request setFailedBlock:^{

        NSError *error = request.error;

        NSLog(@"请求网络出错:%@",error);

    }];

    





在 NSData *data = request.responseData;这一行报警告:::Capturing \'request\'


 strongly in this block is likely to lead to a retain cycle.......... 



先开始我想应该是内存管理的问题,后来想自己使用了arc应该不存在这个问题吧。。后

来朋友说,block里面不能使用自己自定义的属性,因为block是独立的。。网上查了一下
关于block的使用问题,看的懵懵懂懂不太明白,没有理解。。。。没有明白。。这个和

我的程序死掉有什么关系??我写的代码,

照点击打开链接这个网站的写的......


嗯,现在我把设置缓存的代码注释掉了,程序就可以了。。。这个跟缓存有关么?

------------------------------------------------------------------------

点击打开链接   Block的Retain Cycle的解决方法
---------------------------------------

点击打开链接   使用ASIHTTPRequest和ASIDownloadCache实现本地缓存


好啦,这个问题是设置缓存的问题。。

ViewController.m



@interface ViewController (){


    ASIDownloadCache *myCache; 

}


修改缓存的代码:

//    设置缓存--

     ASIDownloadCache *cache = [[ASIDownloadCachealloc]init];//创建缓存对象

     myCache = cache;

    

   //路径

     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);

    

   NSString *documentDirectory = [pathsobjectAtIndex:0];

    NSLog(@"path-%@",documentDirectory);

    

    //设置缓存存放路径

    

    [myCachesetStoragePath:[documentDirectorystringByAppendingPathComponent:@"pic"]];

    

    myCache.defaultCachePolicy =ASIOnlyLoadIfNotCachedCachePolicy; //设置缓存策略

    

    //每次请求会将上一次的请求缓存文件清除

    //    request.cacheStoragePolicy = ASICacheForSessionDurationCacheStoragePolicy;

    //持久缓存,一直保存在本地(是持久缓存,程序下次启动,缓存仍然还在)

    request.cacheStoragePolicy =ASICachePermanentlyCacheStoragePolicy;

    request.downloadCache = cache;


   -----------------



打印了路径,前往文件夹,输入路径,就的到以下图示:


----------------

源代码:


点击打开链接




4楼wwwang89123昨天 12:27额,换成这个__block ASIFormDataRequest *request = [ASIFormDataRequestrequestWithURL:url];,也不行么?Re: willingYaTou昨天 12:34回复wwwang89123n报错:2013-10-15 12:27:36.349 ASIHttpRequestDemo 1[1715:4107] -[__NSCFSet defaultCachePolicy]: unrecognized selector sent to instance 0x7246b20n2013-10-15 12:27:36.351 ASIHttpRequestDemo 1[1715:c07] 请求网络出错:Error Domain=ASIHTTPRequestErrorDomain Code=10 "NSInvalidArgumentException" UserInfo=0xf22db00 {NSLocalizedFailureReason=-[__NSCFSet defaultCachePolicy]: unrecognized selector sent to instance 0x7246b20, NSUnderlyingError=0xf22dae0 "The operation couldn’t be completed. (ASIHTTPRequestErrorDomain error 10.)", NSLocalizedDescription=NSInvalidArgumentException}3楼willingYaTou昨天 12:24http://blog.csdn.net/itianyi/article/details/8715857 Block的Retain Cycle的解决方法n一个使用Block语法的实例变量,在引用另一个实例变量的时候,经常会引起retain cycle。这个问题在使用ASIHTTPRequest的block语法的时候会时不时的碰到。nn<span >/* ViewController.h */ n#import <UIKit/UIKit.h> n ntypedef void (^ABlock)(void); //定义一个简单的Block n n@interface ViewController : UIViewController { n NSMutableArray *_items; n ABlock _block; n} n n@end n n/* ViewController.m */ n n#import "ViewController.h" n n@implementation ViewController n n- (void)viewDidLoad n{ n [super viewDidLoad]; n // Do any additional setup after loading the view, typically from a nib. n _items = [[NSMutableArray alloc] init]; n _block = ^{ n [_items addObject:@"Hello!"]; //_block引用了_items,导致retain cycle。 n }; n} nnXcode在编译以上程序的时候会给出一个警告:Captureing ‘self’ strongly in this block is likely to lead to a retain cycle。原因是_items实际上是self->items。_block对象在创建的时候会被retain一次,因此会导致self也被retain一次。这样就形成了一个retain cycle。2楼willingYaTou昨天 12:24我这个程序逻辑有没有错???那个缓存对不对??1楼wwwang89123昨天 11:21哦,你的程序是crash嘛?还是就只是这一个警告而已?能够请求得到数据么?__block ASIFormDataRequest *request = [ASIFormDataRequestrequestWithURL:url];,你把这一句话这样改一下,试一下看行不行?Re: willingYaTou昨天 12:16回复wwwang89123n2013-10-15 12:24:48.110 ASIHttpRequestDemo 1[1597:1307] -[__NSCFSet defaultCachePolicy]: unrecognized selector sent to instance 0x72730c0n2013-10-15 12:24:48.112 ASIHttpRequestDemo 1[1597:c07] 请求网络出错:Error Domain=ASIHTTPRequestErrorDomain Code=10 "NSInvalidArgumentException" UserInfo=0x7274170 {NSLocalizedFailureReason=-[__NSCFSet defaultCachePolicy]: unrecognized selector sent to instance 0x72730c0, NSUnderlyingError=0x7274150 "The operation couldn’t be completed. (ASIHTTPRequestErrorDomain error 10.)", NSLocalizedDescription=NSInvalidArgumentException}Re: willingYaTou昨天 12:22回复wwwang89123n警告问题,,使用_weak asiformdatarequest *weakRequest=request;nnNSData *data = weakRequest.responseData改了。。现在是它没有执行到block里面去。。。。最后就crash掉了

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