文档章节

Android中遇到的好的博文

Ev4n
 Ev4n
发布于 2016/07/25 13:13
字数 2923
阅读 22
收藏 0
点赞 0
评论 0

(一)Andoird Studio 错误: 非法字符: '\ufeff'

参照链接这里解决。原因是as无法识别BOM的问题。人生中第一次遇到这个问题是大学时写PHP,那时候就牢牢的记住个了。时隔这么多年,在另一款编辑器另一种语言中又遇到了,缘分啊!

(二)关于AlertDialog

这里一模一样的内容) 有关于AlertDialog的基本使用,基本可以参考到了。不过更好的是如何与AlertDialog交互的问题,有一篇文章写得特别好,但是找不到了。

在onClick(DialogInterface,int,int which)中,可以通过DialogInterface的getId来区分弹出的AlertDialog,按键则通过which了。这种情况适合于将所有的AlterDialog的onClick回调全部绑定到自身的情况了。

(三)ListView

这里ListView使用的文章,而这个是关于android.R.layout里面定义的与listview有关的那部分xml说明,值得参考。这个详细的介绍了adapter情况,值得回味一下

简书中的这篇文章简单却很有效的介绍了BaseAdapter的用法,比其他的更加有效,看完之后就基本了解了其原理及应用


(四)自带图标

这里是有关android自带的系统图标,可以通过android.R.drawable/访问,至少用作临时的place holder也可以嘛!

(五)Android问题与之thisActivity.this的区别

这里有关Activity.this与this区别。写过js所以的对于闭包有些害怕,但在这里于是乎还是一目了然。

        fab_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mOptStatus = OperationStatus.Other;
                if (mArea.getCount() == 0) {
                    Toast.makeText(MainApplication.getContext(), "请先圈定范围", Toast.LENGTH_SHORT).show();
                } else {
                    View vv = LayoutInflater.from(MainApplication.getContext()).inflate(R.layout.save_line_dialog, null);
                    save_name_et = (EditText) vv.findViewById(R.id.save_line_et);
                    save_line_ad = new AlertDialog.Builder(getActivity())
                            .setTitle("输入名称")
                            .setView(vv)
                            .setPositiveButton("保存", iActivity.this)
                            .setNegativeButton("取消", null).create();
                    save_line_ad.show();
                }
            }
        });

(六)ListView的onItemLongClick不被触发

这里表述了这两者(LongClick和Click)的过程。默认情况下as自动生成的代码模板,LongClick是返回false。如果想自己触发,则需要手动改成true.

@Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        mItem_index=position;
        del_prj_ad.show();
        return true;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        mItem_index=position;
        open_prj_ad.show();
    }

/*

*    好吧,后来发现即使长按,也没有弹出Dialog,很是奇怪啊,

*    仔细查看后发现是没有注册onItemLongClick,不好意思,但是应该还是有关系的,

*    要不然总会瞎onItemClick的。

*/

这里还有一个对Button或者ImageButton长按的说明,道理相似。

 

(七)org.json.JSONArray没有add方法

这个问题只有去访问该项目的github,不过看完之后还是会惊叹,果然是没有。它本身不打算考虑像ArrayList那样可以add到任意的index(虽然它内部的实现还是使用ArrayList),而通过put(Object o)方法就是将o放到内部List的尾部(直接List.add(o)),而put(index,o)是更改内部index位置的对象,不是想象的add(index,o)的实现。好了,想insert的想法是不能有的。

可以考虑新建对象,但是,开销太大了点,不值得。

(八)Java的泛型

使用泛型,确实是使用java的ArrayList<E>,但是知道这个(或者相似概念)要算是学习C++时涉及到的模板(template)。segmentF的讲解和排版都不错,是个入门的教程。提到的《java编程思想》也确实值得学习。这个的例子还是蛮多。

讲真,能想到用泛型的,估计都是手懒到一定程度了吧。我怎么想到用泛型了呢?不同的类型,却面对着相同的操作。即使是实现了相同的接口,却也无法将类型传递进去,承受着这种手忙脚乱的感觉,突然念叨了Python的好。

public JSONArray returnResult(ArrayList<IInterface> ii)
{
    JSONArray a=new JSONArray();
    for(IInterface i:ii)
    {
        a.put(i.toJson());//看着也可以呀,忘记了不行的写法了
    }
    return a;
}

(九)Activity与Fragment的生存周期

这个事情很烦躁啊,也可能是没认真研究的缘故。这里讲了动态与静态(即xml文件)处理frgment的问题,谁知道是不是坑呢。而这个研究的很细致了,将每一个过程(onCreate,onStart等等)说的很清楚,排版不错呦。

(十)Handler与Looper的机制

这里算是简介,而这里讲的非常透彻,当然在我还没弄清除之前还不能写太多评论。我的代码有些卡顿了。不知为何。慢慢的调试中。

int vol_id=0x01;
    int salt_id=0x02;
    int space_id=0x03;
    Handler mHandler=new Handler(new Handler.Callback(){
        @Override
        public boolean handleMessage(Message msg) {
            Log.i("E","xxxxxx"+ msg.what);
            if(msg.what==vol_id)
                if(vol_tv!=null)
                {
                    vol_tv.setText(vol_tv_text);
                }
            else if(msg.what==salt_id)
                if(salt_tv!=null)
                {
                    salt_tv.setText(salt_tv_text);
                }
            else if(msg.what==space_id)
                if(space_tv!=null)
                {
                    space_tv.setText(space_tv_text);
                }
            return false;
        }
    });

(十一)TextView中getBackground返回为null

网络上能搜索到的关于设置和获取TextView的代码很多,除了有关于考虑android版本情况的,其他的几乎是一致的。

然而自己的代码确实是总返回null,调试中可以看到mColor为空。在代码中,自己的空间是从xml布局中直接获取的,虽然在xml的父container中设置了backgroud,但是通过findViewById获得的还是努力了。最后不得不先尝试,即在findViewById之后手动调用setBackgroundColor,这样再次获取时就成功了。

Stack overflow中的这篇问题中的答案解析比较全面,但还是没说我的这种情况。

 

(十二)关于使用Sqlite作为本地存储的通用开头

自我感觉,这种方式的初始化应该会用得更多,所以记录下来,直接copy就可以了。其中包括了数据库路径优先外置存储器选择,适当改改也可以进行单利化。

public class PathDatabase extends SQLiteOpenHelper {
    public static int version=1;
    public static String db_name="name.db";
    String table_name="table";
    SQLiteDatabase mSQLiteDatabase;
    private PathDatabase(Context c,String full_db_name){
        super(c,full_db_name,null,PathDatabase.version);
    }
    public static PathDatabase getInstance(Context c){
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)&&Environment.isExternalStorageEmulated())
        {
            return new PathDatabase(c,Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+db_name);
        }else {
            return new PathDatabase(c,db_name);
        }
    }

关于sqlite获得id的问题,insert方法确实可以获得插入数据的rowid,文档上就这么写的。

public long insert (String table, String nullColumnHack, ContentValues values)

Added in API level 1

Convenience method for inserting a row into the database.

Parameters

table the table to insert the row into
nullColumnHack optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided values is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your values is empty.
values this map contains the initial column values for the row. The keys should be the column names and the values the column values

Returns

  • the row ID of the newly inserted row, or -1 if an error occurred

但是呢,又有提出,使用rowid作为主键是很不安全的,因为rowid会更改,做法就是

If you don’t want to read the whole post then just do this: Everytime you create a table with sqlite make sure to have an INTEGER PRIMARY KEY AUTOINCREMENT column (the rowid column will be an alias to this one).

所以我考虑就这么定义吧,但愿insert的时候返回的是这货。

(十三)onBackPressed

对于现如今的系统,Activity中有处理按返回键的事件,public void onBackPressed(),当然自动生成的会有super方法,也就会触发退出事件,一般会直接改掉。这个是具体的介绍,而这个介绍了双击退出键退出程序的写法,无非就是用时间差,简单而高效有用。我还想到用2秒自毁线程,然后在主线程中判断是否运行,实际上会挺犯不上的。

Simple is better than complex
public class Common {
    public static long last_time_click=-1;
    public static int backclick_internal=2;
}

@Override
    public void onBackPressed() {
        if((System.currentTimeMillis()-Common.last_time_click)<Common.backclick_internal){
            finish();
            System.exit(0);
        }else{
            Common.last_time_click=System.currentTimeMillis();
        }
    }

(十四)动态更改View的宽度等

动态更改是通过LinearLayout.LayoutParams来更改,调用View.setLayoutParams,比如这里说的清楚。但是遇到两个事情:java.lang.ClassCastException和宽度问题。

CastException问题是在给View的时候,但是这里的param应该是其父容器的类型,即在转换的时候(View.getLayoutParam获取的是ViewGroup.LayoutParams对象,需要强制转换)给出正确的类型。这里说明了一下,确实很准确。

RelativeLayout.LayoutParams mLayoutParams;
 public void onClick(View v) {
            mLayoutParams=(RelativeLayout.LayoutParams)mView.getLayoutParams();
            if(mImageButton1.isSelected()){
                mImageButton1.setSelected(false);
                mLayoutParams.width= Util.dip2px(Util.change_map_type_short_width);
            }else{
                mImageButton1.setSelected(true);
                mLayoutParams.width=Util.dip2px(Util.change_map_type_long_width);
            }
            mView.setLayoutParams(mLayoutParams);
}

宽度是因为在代码中赋值给width是像素值,而多数情况下是dip的数值,这需要进行转换计算。这里给了代码,但是感觉通用性不强,于是自己改造了Application类,见(十五)。通过静态方法,将计算的scale值放在第一次运行时计算。

public class Util {
    public static int px2dip(float pxValue) {
        return (int) (pxValue / MyApplication.scale + 0.5f);
    }
    public static int dip2px(float dpValue) {

        return (int) (dpValue * MyApplication.scale+0.5f);
    }
}

 

(十五)全局获取Context对象

这种方式是最为方便的,虽然没有顾忌太多的。这里是博客,下面是根据自己需要改造后配合上面计算像素与dip转换。

public class MyApplication extends Application {
    private  static Context context;

    @Override
    public void onCreate() {
        super.onCreate();
        context=getApplicationContext();
        scale=context.getResources().getDisplayMetrics().density;
    }

    public static Context getContext() {
        return context;
    }
    public static float scale ;
}

(十六)振动器

通过服务获取即可,唯一的就是几个参数:一个是使用一个毫秒数来震动多久,另一个是两个参数,前一个是long数组,两两结合表示停顿时间,震动时间,第二个参数表示循环起始下标,如果使用-1则表示震动一次。具体的参看这里或者这里。代码抄至后者。

vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(2000);//震动指定时间 ,数据类型long,单位为毫秒,一毫秒为1/1000秒
vibrator.vibrate(new long[]{100,10,100,1000}, -1);//按照指定的模式去震动。
vibrator.cancel();//取消震动,立即停止震动。震动为一直震动的话,如果不取消震动,就算退出,也会一直震动

(十七)int类型的List

这个很基础,只可惜没注意过,或者没有学过。应为List以及ArrayList中只能存放继承至Object的对象,对于值类型不支持,但是可以使用其封装为Object的Integer以及类似的对象,比如这里说明的意思。

 

(十八)准确获取储存卡的路径

原本我使用的方法是下面。

public static Database getInstance(Context c){
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)&&Environment.isExternalStorageEmulated())
        {
            return new PathDatabase(c,Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+db_name);
        }else {
            return new Database(c,db_name);
        }
    }

但是发现,储存卡与sdcard的关系不一定,有可能是sdcard1才是储存卡所以需要一个准确的获取方法。

这里讲的非常全面。之前一直使用其他写法。原理以后可以详看(主要是Java的反射机制),下面代码就抄过来了。这个写的也不错,但是内容也差不多,做补充。

    import java.lang.reflect.Method;  
    import android.os.storage.StorageManager;  
      
        // 获取主存储卡路径  
        public String getPrimaryStoragePath() {  
            try {  
                StorageManager sm = (StorageManager) getSystemService(STORAGE_SERVICE);  
                Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", null);  
                String[] paths = (String[]) getVolumePathsMethod.invoke(sm, null);  
                // first element in paths[] is primary storage path  
                return paths[0];  
            } catch (Exception e) {  
                Log.e(TAG, "getPrimaryStoragePath() failed", e);  
            }  
            return null;  
        }  
          
        // 获取次存储卡路径,一般就是外置 TF 卡了. 不过也有可能是 USB OTG 设备...  
        // 其实只要判断第二章卡在挂载状态,就可以用了.  
        public String getSecondaryStoragePath() {  
            try {  
                StorageManager sm = (StorageManager) getSystemService(STORAGE_SERVICE);  
                Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", null);  
                String[] paths = (String[]) getVolumePathsMethod.invoke(sm, null);  
                // second element in paths[] is secondary storage path  
                return paths.length <= 1 ? null : paths[1];  
            } catch (Exception e) {  
                Log.e(TAG, "getSecondaryStoragePath() failed", e);  
            }  
            return null;  
        }  
          
        // 获取存储卡的挂载状态. path 参数传入上两个方法得到的路径  
        public String getStorageState(String path) {  
            try {  
                StorageManager sm = (StorageManager) getSystemService(STORAGE_SERVICE);  
                Method getVolumeStateMethod = StorageManager.class.getMethod("getVolumeState", new Class[] {String.class});  
                String state = (String) getVolumeStateMethod.invoke(sm, path);  
                return state;  
            } catch (Exception e) {  
                Log.e(TAG, "getStorageState() failed", e);  
            }  
            return null;  
        }  

 

 

博客

Hongyang

guolin

© 著作权归作者所有

共有 人打赏支持
Ev4n
粉丝 5
博文 13
码字总数 9845
作品 0
成都
React Native Mac 下打包Android APK

打包的时候遇到了 好多坑 这里记录下~ 主要步骤: 1.android keystore签名的生成 gradle mac下环境变量的配置 3.android studio中的gradle配置。 4.打包 签名的生成 执行完之后,输入本机的 ...

JsLin_ ⋅ 06/18 ⋅ 0

android开发常用工具类、高仿客户端、附近厕所、验证码助手、相机图片处理等源码

Android精选源码 android开发过程经常要用的工具类源码(http://www.apkbus.com/thread-599826-1-1.html) Android类似QQ空间个人主页下拉头部放大的布局效果(http://www.apkbus.com/thread-5...

逆鳞龙 ⋅ 05/29 ⋅ 0

(Mac)反编译Android APK详细操作指南[ApkTool,dex2jar,JD-GUI]

早在4年前我曾发表过一篇关于《Android开发之反编译与防止反编译》的文章,在该文章中我对如何在Windows平台反编译APK做了讲解,如今用Mac系统的同学越来越多,也有很多朋友问我能否出一篇关...

CrazyCodeBoy ⋅ 05/11 ⋅ 0

Android7.0 分屏下 Activity 与 Fragment 生命周期(一)

小菜前段时间整理了一篇关于我们真的了解 Activity 与 Fragment 的生命周期吗?的小博文,整理了基础版的关于 Activity 与 Fragment 的生命周期。 后来又一次被一个大大神问到在 Android7.0...

阿策神奇 ⋅ 06/11 ⋅ 0

Unity发布Android版本

先大概说一下我自己的经历吧,总的大概用了10小时吧。刚开始装的是jre和Android stdio,然后发现要装的是JDK和SDK,然后去装JDK和SDK,装JDK很顺利,装SDK失败了,原因未知。后面是用 Androi...

a_clear_chen ⋅ 05/08 ⋅ 0

高手问答第 198 期 — Android 十年,一起深入剖析 Android 新特性

OSCHINA 本期高手问答(2018 年 5 月 22 日 — 5 月 28 日)我们请来了强波@paulQuei和大家就关于剖析 Android 新特性方面的问题进行讨论。 强波,江苏南京人,现居住在浙江杭州。就职于阿里巴...

局长 ⋅ 05/22 ⋅ 0

Android源码浅析(三)——Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机

Android源码浅析(三)——Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机 最近比较忙,而且又要维护自己的博客,视频和公众号,也就没仔细的梳理源码的...

刘桂林 ⋅ 2016/06/15 ⋅ 0

最新靠谱可用的 Mac 环境下 FFmpeg 环境搭建

大家好,我是光源。 最近在尝试搭建 FFmpeg 开发环境时遇到一个蛋疼的事,Google 了 N 篇文章竟然没有一篇是可以跑起来的! 少部分教程是给出了自我矛盾的配置(是的,按照贴出来的代码和配置...

光源_Android ⋅ 05/13 ⋅ 0

android仿摩拜单车APP、炫酷RecyclerView、卡片滑动、仿饿了么点餐、自定义索引等源码

Android精选源码 Android自定义索引源码(http://www.apkbus.com/thread-599163-1-1.html) LayoutManager实现的卡片滑动(http://www.apkbus.com/thread-599396-1-1.html) android仿摩拜单车A......

逆鳞龙 ⋅ 05/22 ⋅ 0

Android P 版本号为 9,第三个开发者预览版有这些变化

近日,Google 如期放出了 Android P 的第三个开发者预览版(以下简称 DP3)。DP3 主要面向应用开发者,将该版本操作系统的 API 等级正式确定为 API level 28,开发者可以借助相关的 SDK 面向...

h4cd ⋅ 06/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 35分钟前 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 43分钟前 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 49分钟前 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

容器之查看minikue的environment——minikube的环境信息

执行如下命令 mjduan@mjduandeMacBook-Pro:~/Docker % minikube docker-envexport DOCKER_TLS_VERIFY="1"export DOCKER_HOST="tcp://192.168.99.100:2376"export DOCKER_CERT_PATH="/U......

汉斯-冯-拉特 ⋅ 昨天 ⋅ 0

mysql远程连接不上

设置了root所有hosts远程登录,可是远程登录还是失败,原因可能如下: 登录本地数据库 mysql -uroot -p123456 查询用户表 mysql> select user,host,password from mysql.user; 删除密码为空的...

冰公子 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部