当前位置:  编程技术>移动开发
本页文章导读:
    ▪SD卡路径有关问题以及怎么获取SDCard 内存        SD卡路径问题以及如何获取SDCard 内存        昨天在研究拍照后突破的存储路径的问题,开始存储路径写死为:    private String folder = "/sdcard/DCIM/Camera/"(SD卡上拍照程序的图片存储路径.........
    ▪ Object-C学习(5)        Object-C学习(五) 引用: http://blog.csdn.net/huanglx1984/article/details/4303041iPhone 程序开发时内存的管理 在开发iPhone 程序时,一定要特别小心内存的管理。其实基本的道理很简单,就像我们以前.........
    ▪ 解决ActivityGroup的sub Activity中spinner的WindowManager$BadTokenException的有关问题       解决ActivityGroup的sub Activity中spinner的WindowManager$BadTokenException的问题 在ActivityGroup的sub activity中直接使用Spinner会遇到下面的异常信息:  ERROR/AndroidRuntime(964): FATAL EXCEPTION: main  ERROR/AndroidRuntime(.........

[1]SD卡路径有关问题以及怎么获取SDCard 内存
    来源: 互联网  发布时间: 2014-02-18
SD卡路径问题以及如何获取SDCard 内存
   
   昨天在研究拍照后突破的存储路径的问题,开始存储路径写死为:    private String folder = "/sdcard/DCIM/Camera/"(SD卡上拍照程序的图片存储路径); 后来发现这样写虽然一般不会出错,但不是很好,因为不同相机,可能路径会出问题。较好的方法是通过Environment 来获取路径,最后给出一个例子,教你怎样获取SDCard 的内存,显示出来告诉用户。讲述的内容如下:

    0、获取sd卡路径。
    1、讲述 Environment 类。
    2、讲述 StatFs 类。
    3、完整例子读取 SDCard 内存


0、获取sd卡路径
方法一: private String folder = "/sdcard/DCIM/Camera/"(SD卡上拍照程序的图片存储路径); //写死绝对路径,不赞成使用

方法二:
public String getSDPath(){
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState()  
                              .equals(android.os.Environment.MEDIA_MOUNTED);  //判断sd卡是否存在
        if  (sdCardExist)  
        {                                 
            sdDir = Environment.getExternalStorageDirectory();//获取跟目录
          }  
        return sdDir.toString();
        
    }


然后:在后面加上斜杠,在加上文件名
   String fileName = getSDPath() +"/" + name;//以name存在目录中


1、讲述 Environment 类
Environment 是一个提供访问环境变量的类。
Environment 包含常量:

    MEDIA_BAD_REMOVAL
    解释:返回getExternalStorageState() ,表明SDCard 被卸载前己被移除
    MEDIA_CHECKING
    解释:返回getExternalStorageState() ,表明对象正在磁盘检查。
    MEDIA_MOUNTED
    解释:返回getExternalStorageState() ,表明对象是否存在并具有读/写权限
    MEDIA_MOUNTED_READ_ONLY
    解释:返回getExternalStorageState() ,表明对象权限为只读
    MEDIA_NOFS
    解释:返回getExternalStorageState() ,表明对象为空白或正在使用不受支持的文件系统。
    MEDIA_REMOVED
    解释:返回getExternalStorageState() ,如果不存在 SDCard 返回
    MEDIA_SHARED
    解释:返回getExternalStorageState() ,如果 SDCard 未安装 ,并通过 USB 大容量存储共享 返回
    MEDIA_UNMOUNTABLE
    解释:返回getExternalStorageState() ,返回 SDCard 不可被安装 如果 SDCard 是存在但不可以被安装
    MEDIA_UNMOUNTED
    解释:返回getExternalStorageState() ,返回 SDCard 已卸掉如果 SDCard  是存在但是没有被安装

Environment 常用方法:

    方法:getDataDirectory()
    解释:返回 File ,获取 Android 数据目录。
    方法:getDownloadCacheDirectory()
    解释:返回 File ,获取 Android 下载/缓存内容目录。
    方法:getExternalStorageDirectory()
    解释:返回 File ,获取外部存储目录即 SDCard
    方法:getExternalStoragePublicDirectory(String type)
    解释:返回 File ,取一个高端的公用的外部存储器目录来摆放某些类型的文件
    方法:getExternalStorageState()
    解释:返回 File ,获取外部存储设备的当前状态
    方法:getRootDirectory()
    解释:返回 File ,获取 Android 的根目录

2、讲述 StatFs 类
StatFs 一个模拟linux的df命令的一个类,获得SD卡和手机内存的使用情况
StatFs 常用方法:

    getAvailableBlocks()
    解释:返回 Int ,获取当前可用的存储空间
    getBlockCount()
    解释:返回 Int ,获取该区域可用的文件系统数
    getBlockSize()
    解释:返回 Int ,大小,以字节为单位,一个文件系统
    getFreeBlocks()
    解释:返回 Int ,该块区域剩余的空间
    restat(String path)
    解释:执行一个由该对象所引用的文件系统

3、完整例子读取 SDCard 内存
存储卡在 Android 手机上是可以随时插拔的,每次的动作都对引起操作系统进行 ACTION_BROADCAST,本例子将使用上面学到的方法,计算出 SDCard 的剩余容量和总容量。代码如下:
package com.terry;

import java.io.File;
import java.text.DecimalFormat;

import android.R.integer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public
class getStorageActivity extends Activity {
    private Button myButton;
    /** Called when the activity is first created. */
    @Override
    public
void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findView();
        viewHolder.myButton.setOnClickListener(new OnClickListener() {
            
            @Override
            public
void onClick(View arg0) {
                // TODO Auto-generated method stub
                getSize();
            }
        });
    }
   
   
    void findView(){
        viewHolder.myButton=(Button)findViewById(R.id.Button01);
        viewHolder.myBar=(ProgressBar)findViewById(R.id.myProgressBar);
        viewHolder.myTextView=(TextView)findViewById(R.id.myTextView);
    }
   
   
   
    void getSize(){
        viewHolder.myTextView.setText("");
        viewHolder.myBar.setProgress(0);
        //判断是否有插入存储卡

if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            File path =Environment.getExternalStorageDirectory();
            //取得sdcard文件路径
            StatFs statfs=new StatFs(path.getPath());
            //获取block的SIZE

long blocSize=statfs.getBlockSize();
            //获取BLOCK数量

long totalBlocks=statfs.getBlockCount();
            //己使用的Block的数量

long availaBlock=statfs.getAvailableBlocks();
            
            String[] total=filesize(totalBlocks*blocSize);
            String[] availale=filesize(availaBlock*blocSize);
            //设置进度条的最大值

int maxValue=Integer.parseInt(availale[0])
            *viewHolder.myBar.getMax()/Integer.parseInt(total[0]);
            viewHolder.myBar.setProgress(maxValue);
            String Text="总共:"+total[0]+total[1]+"\n"
+"可用:"+availale[0]+availale[1];
            viewHolder.myTextView.setText(Text);
            
        }else
if(Environment.getExternalStorageState().equals(Environment.MEDIA_REMOVED)){
            Toast.makeText(getStorageActivity.this, "没有sdCard", 1000).show();
        }
    }
   
    //返回数组,下标1代表大小,下标2代表单位 KB/MB
    String[] filesize(long size){
        String str="";
        if(size>=1024){
            str="KB";
            size/=1024;
            if(size>=1024){
                str="MB";
                size/=1024;
            }
        }
        DecimalFormat formatter=new DecimalFormat();
        formatter.setGroupingSize(3);
        String result[] =new String[2];
        result[0]=formatter.format(size);
        result[1]=str;
        return result;
    }
}


   原文:http://www.ophonesdn.com/forum/thread-2632-3-1.html
最近太能Copy了。

    
[2] Object-C学习(5)
    来源: 互联网  发布时间: 2014-02-18
Object-C学习(五)
引用: http://blog.csdn.net/huanglx1984/article/details/4303041



iPhone 程序开发时内存的管理



在开发iPhone 程序时,一定要特别小心内存的管理。其实基本的道理很简单,就像我们以前写C++ 程序一样,new 和delete 要成对出现。问题是在某些时候,我们没有意识到自己使用了new 。



Objective-C 中对内存的管理采用引用计数的技术。简单说就是,当我们拥有一个变量的时候,这个变量的计数就加1,当我们释放这个变量的时候,这个变量的计数就减1。当计数为0时,这个变量就可以合法的被删除了。



1)alloc 很明显,这个函数调用之后,变量的计数加1。所以在调用alloc 之后,一定要调用对应的release

2)retain 保留一个对象。调用之后,变量的计数加1。或许不是很明显,我们举个例子

- (void) setName : (NSString*) name {

     [name retain];

     [myname release];

     myname = name;


}



我们来解释一下:设想,用户在调用这个函数的时候,他注意了内存的管理,所以他小心的写了如下代码:

NSString * newname = [[NSString alloc] initWithString: @"John"];

[aClass setName: newname];

[newname release];



我们来看一看newname的计数是怎么变化的。首先,它被alloc,count = 1; 然后,在setName中,它被retain, count = 2; 最后,用户自己释放newname,count = 1,myname指向了newname。这也解释了为什么需要调用[myname release]。我们需要在给myname赋新值的时候,释放掉以前老的变量。

3)copy 返回某个对象的一个拷贝。这个拷贝是一个新的对象,它的计数为1,需要在将来被release。



基本上,所有带有alloc, retain, copy的函数,都会使得变量的计数加1。因此在调用完这些方法之后,要小心release。另外还有一些初始化函数,它们没有带有alloc , retain 或者copy 的字样,比如stringWithFormat ,它们并不会使变量计数加1。





Autorelease

在Objective-C中,这个概念很象Java中的Garbage Collection 。它会把内存的管理交给另一个系统(autorelease pool)。在某些时候,我们在一个函数内部创建(alloc )了一个变量,但是我们无法在函数内部将这个变量释放(确实会有这种情况出现。。。),而显然,我们不可能在函数外部释放这个变量,这时候就可以借助Autorelease来帮忙了。据说,我们应该尽量自己管理内存,不要随便交给Autorelease。天下没有免费的午餐啊,呵呵。自己省了事,但是也失去了对内存的控制。。。天知道autorelease pool啥时候才会给你release啊。。。








Objective-C 提供了一些容器,如NSArray , NSDictionary , NSSet 等等,加入容器的对象都会使计数加1。这和C++ 中的容器类很相似。我们在C++ 中,常常看到:

void addElement( vector<ClassA>& my_list; )


{


    ClassA object1;

    my_list.push_back(object1);


}

虽然object1 是一个临时变量,在函数调用结束后会自动销毁,我们仍然可以安全的添加元素。

所以在Objective-C 中,我们也能看到如下代码:

NSMutableArray * array = [[NSMutableArray alloc] init];


NSNumber *num = [[NSNumber alloc] initWithInt: 1];

[array addObject: num ];

[num release];

... ...




再看两个编码上可以考量的地方:

1)为什么我们很少看见有人这样写代码:

AClass * class = [AClass alloc];

[class init];

而基本上都是 AClass * class = [[AClass alloc] init];

原因很简单,因为我们需要确保当init 调用失败的时候,class是一个无效的值(nil)。如果使用第一种方式,我们无法通过class的值知道init是否调用成功。这也告诉我们,在实现自己的init 方法时,需要在失败的时候返回nil 。

2)一般在dealloc方法中,我们都会释放一些变量,所以我们经常看到

- (void) dealloc {

    [ var release];

    [ super dealloc];


}

这样写当然没有错,但是我看见过某些“geek ”分析到:

在调用release 之后,虽然变量被释放了,可是它的值仍然是有效的。就好像我们在C++ 里面,delete 一个变量之后,一个好的习惯是,接着将这个变量赋值为0。所以,最优的方法是加上var = nil;



以上就是一些使用Objective-C 需要注意的地方。



到这里,我基本上说完了关于Objective-C 的基础内容,当然,它本身还有很多东西,不可能通过短短几篇博客就说完。而且我使用Objective-C 的时间也不长,无法做到面面俱到。但是,个人认为掌握这些基本概念之后,我们就可以开始iPhone 程序的开发了,在开发的过程中继续加深对Objective-C 的理解

    
[3] 解决ActivityGroup的sub Activity中spinner的WindowManager$BadTokenException的有关问题
    来源: 互联网  发布时间: 2014-02-18
解决ActivityGroup的sub Activity中spinner的WindowManager$BadTokenException的问题

在ActivityGroup的sub activity中直接使用Spinner会遇到下面的异常信息:

 ERROR/AndroidRuntime(964): FATAL EXCEPTION: main
 ERROR/AndroidRuntime(964):android.view.WindowManager$BadTokenException: Unable to add window -- token   android.app.LocalActivityManager$LocalActivityRecord@44f02d20   is not valid; is your activity running?
 ERROR/AndroidRuntime(964):      at android.view.ViewRoot.setView(ViewRoot.java:505)
 ERROR/AndroidRuntime(964):      at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
 ERROR/AndroidRuntime(964):      at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
 ERROR/AndroidRuntime(964):      at android.view.Window$LocalWindowManager.addView(Window.java:424)
 ERROR/AndroidRuntime(964):      at android.app.Dialog.show(Dialog.java:241)
 ERROR/AndroidRuntime(964):      at android.app.AlertDialog$Builder.show(AlertDialog.java:802)
 ERROR/AndroidRuntime(964):      at android.widget.Spinner.performClick(Spinner.java:257)
 ERROR/AndroidRuntime(964):      at android.view.View$PerformClick.run(View.java:8816)
 ERROR/AndroidRuntime(964):      at android.os.Handler.handleCallback(Handler.java:587)
 ERROR/AndroidRuntime(964):      at android.os.Handler.dispatchMessage(Handler.java:92

…………………………………………

 

 ·第一,你需要在你的sub activity的oncreate方法中获得content view,而不是直接调用系统提供的setContentView(question_activity);

 

我的程序中代码如下:

     View contentView = LayoutInflater.from(getParent().getParent()).inflate(R.layout.question_activity, null); 
     setContentView(contentView);

     spinner = (Spinner) contentView.findViewById(R.id.spinner_a);
    System.out.println(" 当前选中的spinner = "+spinner.getSelectedItem().toString());

说明:

    R.layout.question_activity:是你当前Activity的布局文件。

 

·第二,要注意:

 LayoutInflater.from(getParent().getParent())中from()的参数,是你要显示Spinner的Dialog的页面。

 

·我认为最主要的原因是:

   Spinner的选项是以Dialog的形式显示的(上面的异常信息:at android.app.Dialog.showDialog.java)),是需要显示在总体页面之上的。

     比如:

    ActivityGroup1里面一个ActivityGroup2,而ActivityGroup2中有一个Activity,在这个Activity里有我们的Spinner,那么点击Spinner弹出的Dialog是显示在ActivityGroup1之上的,而不是显示在ActivityGroup2或者Activity之上的。

具体请查看:  http://www.anddev.org/view-layout-resource-problems-f27/how-to-fix-this-windowmanager-badtokenexception-t16555.html


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