Android 学习记录及所遇到的坑

来源:互联网 发布:c语言谭浩强第五 编辑:程序博客网 时间:2024/06/17 06:22


一、关于SwipeRefreshLayout的坑


众所周知,SwipRefreshLayout可以手动停止刷新动画,只需要调用SwipeRefreshLayout.setRefreshing(false).可是当我们需要手动开启动画时候,SwipeRefreshLayout.setRefreshing(true)将不会生效。其真正的手动开启动画需要调用

SwipeRefreshLayout.post(new  Runnable(){          Public void run(){              SwipeRefreshLayout.setRefreshing(true)          }});


这样我们就可以实现手动调用动画了。


二、Rtrofit2使用详解


了解Retrofit2中的网络访问常用注解接口,其实这些接口都是在retrofit2.http这个包下面的

1@GET GET网络请求方式
2@POST POST网络请求方式
3@Headers()头信息参数
4@Path() 路径参数,替换url地址中{ }所括的部分
5@Query() 查询参数,将在url地址中追加类似“page=1”的字符串,形成提交给服务端的请求参数
6@QueryMap查询参数集合,将在url地址中追加类似
“type=text&username=abc&password=123”的字符串
7@FormUrlEncoded对表单域中填写的内容进行编码处理,避免乱码
8@Field() 指定form表单域中每个空间的额name以及相应的数值
9@FieldMap表单域集合
10@Multipart Post提交分块请求,如果上传文件,必须指定Multipart
11@Body Post提交分块请求

 //获取Retrofit对象,设置地址        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://localhost")                .client(OK_HTTP_CLIENT)//设置client 我们可以放入一个okhttpClient,便于我们设置超时时间                .build();  //创建RequstService        创建你的RequstService接口类        @GET        //定义返回的方法,返回的响应体使用了ResponseBody        Call<ResponseBody> getString(@Url String url);        @FormUrlEncoded        @POST        Call<ResponseBody> post(@Url String url, @FieldMap Map<String, String> params);(post请求中用到了@FieldMap,所以必须在方法前加上@FormUrlEncoded否则将会报错)        通过Rtrofit对象创建  retrofit.create(你的RequstService类);   //发起请求如果是post请求需要传入一个map    Call<ResponseBody> call = requestServices.post(url,pamars);        call.enqueue(new Callback<ResponseBody>() {            @Override            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {                if (response.isSuccessful()){                    try {                        Log.i("cc",response.body().string());                    } catch (IOException e) {                        e.printStackTrace();                    }                }            }            @Override            public void onFailure(Call<ResponseBody> call, Throwable t) {                Log.i("cc","访问失败");            }        });

注意:关于retrofit2baseurl的问题 如果设置了baseurl则可以在请求时传入接口进行拼接即可。

组合一://成功

baseUrl("http://api.m.mtime.cn/")@GET("onebox/basketball/nba?key=98020a1e920819b8ff4fcfbdd7747f8c")  Observable<NBA> getNBA2();

组合二://成功

baseUrl("http://api.m.mtime.cn/")@GET("onebox/basketball/nba?key=98020a1e920819b8ff4fcfbdd7747f8c")  Observable<NBA> getNBA2();

三、Parcelable的使用



Parcel就是一个存放读取数据的容器, android系统中的binder进程间通信(IPC)就使用了Parcel类来进行客户端与服务端数据的交互,而且AIDL的数据也是通过Parcel来交互的。在Java空间和C++都实现了Parcel,由于它在C/C++中,直接使用了内存来读取数据,因此,它更有效率

最重要的是其可以实现通过intent进行传递。

在使用时把需要传递的类implement Parcelable即可,完成其必要方法。

 

四、SQLiteDataBase



通过SQLiteDataBase来打开外部数据库。首先把数据库加载到本地,通过输入流实现。

   然后通过SQLiteDataBase来打开数据库

  Db = SQLiteDataBase.openOrCreateDatabase(dbfile,null);

   查找

  

Cursor cursor = db.query(表名,null,null,null,null,null,null);//返回游标


   查找结束后关闭游标。


五、关于activity及fragment生命周期的监听



Application中可以监听所有activity的生命周期。在Activity中可以监听其所包含的fragment的生命周期。

activity生命周期的监听需要在application中调用registerActivityLifeecycleCallbacks方法

fragement生命周期的监听需要在其所属的activity中通过fragmentManager来调用registerFragementLifeecycleCallbacks方法

/**     * 在activity内监听fragment的生命周期     */    public void setRegisterFragmentLifecycleCallbacks()    {        FragmentManager fragmentManager = getSupportFragmentManager();        fragmentManager.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() {            @Override            public void onFragmentResumed(FragmentManager fm, Fragment f) {                super.onFragmentResumed(fm, f);                TCAgent.onPageStart(MainActivityNew.this, f.getClass().getName());            }            @Override            public void onFragmentPaused(FragmentManager fm, Fragment f) {                super.onFragmentPaused(fm, f);                TCAgent.onPageEnd(MainActivityNew.this, f.getClass().getName());            }        },false);    }


六、关于Android File.delete删除文件不够彻底的问题



在调用file.delete方法前我们必须发送一条广播告诉手机我们准备删除该文件,以达到彻底删除文件。

Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);Uri uri = Uri.fromFile(file);Intent.setData(uri);Context.sendBroadcast(intent);file.delete();


七、关于安卓7.0不允许使用Intent直接打开文件,必须使用FileProvider


使用FileProvider的方法

1、mainfest中注册

           <provider              android:name="android.support.v4.content.FileProvider"              android:authorities="com.mydomain.fileprovider"              android:exported="false"              android:grantUriPermissions="true">         </provider>  

2、res文件下创建xml文件目录下创建新文件,内容如下:

     <file-path name="" path="">对应Context.getFilesDir();

     <cache-path name="" path="">对应getCacheDir();

     <external-path name="" path="">对应Environment.getExternalStorageDirectory();

     <external-cache-path name="" path="">对应Context.getExternalCacheDir();

3. Uri的创建   

Uri uri = getUriForFile(content,authorities,file);

4. 重点为URI临时授权

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

八、android6.0以后某些敏感权限需要动态申请



 /** * 请求授权 */private void requestPermission(){    if (Build.VERSION.SDK_INT >= 23) {        int checkCallPhonePermission = ContextCompat.checkSelfPermission                (this, Manifest.permission.CALL_PHONE);        if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {            //在String[]中传入需要申请的权限           ActivityCompat.requestPermissions(this,                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);        }        else{            //sendHomework();           //已经拥有了权限          }    }    else {        }}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults) {    switch (requestCode) {        case 1:            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                //sendHomework();                //获取权限成功后的处理            }            else {               //showToast("fail");                //获取权限失败的处理            }            break;        default:            super.onRequestPermissionsResult(requestCode, permissions, grantResults);    }}

需要动态申请的权限

危险权限和权限组列表




九、关于TransactionTooLargeException异常


     该异常中文意思传输数据过大异常,造成该异常的原因应该是通过Bundle进行数据传输时,数据过大造成的,Bundle进行数据传输严格限制共享区域缓存大小只有1M。

     从以上异常的描述,可以总结出现该异常的原因:
  • 跨进程方法调用
  • 调用的方法带的参数或者返回值占用较多内存
  • 同一时刻方法调用次数太多
      解决办法

  • 压缩数据
  • 减少跨进程传输方法的调用
  • 减少同一时刻方法调用次数



原创粉丝点击