• Android -- 经验分享(二)


    目录                                                                                  

    1. 自定义两个View进行画图,让其各自刷新重绘   
    2. Activity设为singleTop,长按Home键启动的问题           
    3. Activity设为singleTop,长按Home键启动问题
    4. Android软键盘挡住界面        
    5. Android使用AsyncTask下载图片,最好使用WeakReference  
    6. Android webview 加载网络视频
    7. Android 开发中的网络下载策略 与 文件缓存策略 
    8. Android中ListView的addFooterView不显示的问题
    9. Android自动弹出软键盘       

    自定义两个View进行画图,让其各自刷新重绘                                      

    我将屏幕分为左右两部分,并且自定义了绘图类drawOneView和drawTwoView,它们都继承View类,其中drawOneView在屏幕左边显示,drawTwoView在右边显示,在drawOneView中能够通过invalidate()函数,使其重绘,但是在drawTwoView中就不能通过invalidate()函数使drawTwoView进行重绘了,这是为什么呢?并且当drawOneView进行重绘的时候,怎么也会带动drawTwoView重绘,它们应该是分别由各自的类进行控制的,为什么会出现这种情况呢?

    一个用Invalidate(),另外一个用postInvalidate()就可以刷新了

    就是在你需要刷新UI的地方分别调用Invalidate(),postInvalidate()就可以了。

    Activity设为singleTop,长按Home键启动的问题                                    

    若将Activity设置为singleTop的,则,按Home键之后,再长按启动时候,Home键的启动机制里面,好像会重新启动被设置为singleTop的Activity,尽管你的singleTop的Activity已经finish或者整个程序已经结束了。

    目前的解决办法是:做标记,然后在被设置为singleTop的Activity里做拦截

    Android软键盘挡住界面                                                              

    AndroidManifest.xml 中设置 
    android:windowSoftInputMode="stateUnspecified|adjustPan"
    不挤压屏幕,反之为把界面挤压上去。
    <activity android:name=".activity.MainTabActivity" android:theme="@android:style/Theme.NoTitleBar"
                android:configChanges="keyboardHidden|orientation" android:screenOrientation="portrait"
                android:launchMode="singleTask" android:windowSoftInputMode="stateUnspecified|adjustPan">
    </activity>
    需要注意的是:如果是TabActivity里面的一个Activity有EditText有软键盘弹出的时候,在该Activity设置没有作用,需要在TabActivity里设置。

    Android使用AsyncTask下载图片,最好使用WeakReference                      

    有些人喜欢用Android提供的AsyncTask,但事实上AsyncTask的问题更加严重,Thread只有在run函数不结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了ThreadPoolExcutor,该类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。

    这种线程导致的内存泄露问题应该如何解决呢?

    第一、将线程的内部类,改为静态内部类。

    第二、在线程内部采用弱引用保存Context引用。

    解决的模型如下:

    public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget> extends  
            AsyncTask<Params, Progress, Result> {  
        protected WeakReference<WeakTarget> mTarget;  
      
        public WeakAsyncTask(WeakTarget target) {  
            mTarget = new WeakReference<WeakTarget>(target);  
        }  
      
        /** {@inheritDoc} */  
        @Override  
        protected final void onPreExecute() {  
            final WeakTarget target = mTarget.get();  
            if (target != null) {  
                this.onPreExecute(target);  
            }  
        }  
      
        /** {@inheritDoc} */  
        @Override  
        protected final Result doInBackground(Params... params) {  
            final WeakTarget target = mTarget.get();  
            if (target != null) {  
                return this.doInBackground(target, params);  
            } else {  
                return null;  
            }  
        }  
      
        /** {@inheritDoc} */  
        @Override  
        protected final void onPostExecute(Result result) {  
            final WeakTarget target = mTarget.get();  
            if (target != null) {  
                this.onPostExecute(target, result);  
            }  
        }  
      
        protected void onPreExecute(WeakTarget target) {  
            // No default action  
        }  
      
        protected abstract Result doInBackground(WeakTarget target, Params... params);  
      
        protected void onPostExecute(WeakTarget target, Result result) {  
            // No default action  
        }  
    }

    Android webview 加载网络视频                                                     

    webView.loadUrl(video_url);
    webView.setInitialScale(50);
    WebSettings setting = webView.getSettings();
    setting.setUseWideViewPort(true);
            setting.setJavaScriptEnabled(true); //Support JavaScript
            setting.setPluginsEnabled(true); //Support Plugins, for example just like flash plugin.
            setting.setSupportZoom(true); //Zoom Control on web (You don't need this if ROM supports Multi-Touch  
            setting.setBuiltInZoomControls(true); //Enable Multitouch if supported by ROM
            
            webView.setWebViewClient(new MyWebViewClient());
    
    
    public class MyWebViewClient extends WebViewClient  {      
    
    private ProgressDialog loadingBar;
    
    
    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        loadingBar=ProgressDialog.show(mActivity, null, "正在加载…");
        super.onPageStarted(view, url, favicon);
    }
    
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);  // webview里面的链接还在同一个页面中加载 
            return true;  
    }
    
    
    @Override
    public void onPageFinished(WebView view, String url) {
        if(loadingBar.isShowing()){
            loadingBar.dismiss();
        }
        super.onPageFinished(view, url);
    }         
      
    @Override
    public void onReceivedError(WebView view, int errorCode,
                   String description, String failingUrl) {
        Toast.makeText(mActivity, "加载出错!", Toast.LENGTH_LONG).show();
        final AlertDialog alertDialog = new AlertDialog.Builder(mActivity).create();
        alertDialog.setTitle("ERROR");
        alertDialog.setMessage(description);
        alertDialog.setButton("OK", new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which) { 
                alertDialog.dismiss();
            }
        });
         alertDialog.show();
    }
    }

    Android 开发中的网络下载策略 与 文件缓存策略                                 

    一般的缓存策略是:
    一级内存缓存、二级文件缓存(数据库也算作文件缓存)、三级网络数据

    一、网络下载的缓存策略
    关于网络下载文件(图片、音频、视频)的基本策略:
    1.不要直接下载到目标文件,应使用temp文件作中转,以确保文件的正确性与完整性,流程如下:
    a)以网络目标文件名 A 生成唯一的本地目标文件名 B
    b)以本地目标文件名 B 生成唯一的本地临时文件名 T
    c)下载文件到 T 中
    d)下载完毕,校验文件 T 的正确性与完整性
    e)若不正确或不完整则 delete 文件 T,并返回 false
    f)校验完毕后,将文件 T 重命名 或 复制到 B 文件
    g)最后的清理现场,删除临时文件 T,成功后,返回 true
    2.尽力提供文件正确性与完整性的校验:
    a)正确性:比如 MD5/Hash Code 比对、文件格式的比对。
    b)完整性:比如 文件大小是否一致、图片的数据是否正确(图片文件头中提供了相关信息)
    3.考虑对于下载到本地的文件是否需要再做二次加工,可以思考以下情况:
    a)比如网络源始图片的大小为800*600,而我们需要作为缩略图的大小为160*145,所以考虑对下载后的文件进行裁剪,再保存,对于源始文件则直接删除。

    二、文件缓存策略:
    1.需要唯一的缓存文件的对应I/O key,一般可以使用 hashcode。
    2.若是同一个文件,以不同的时间,可以考虑,先清本地缓存,再下载新的缓存到本地。
    3.同一文件也可以加上时间戳后,再生成唯一hashcode。
    4.生成文件缓时,也许需要作以下全面的考虑:

    a)sdcard是否已经没有空间(这个需求是存在的,但几乎没有人会考虑到,一旦发生,必crash)。
    b)缓存的清理策略。每日、每周定时清理?到达一个阀值后,自动清理?(若无清理策略,把垃圾数据一直当个宝一相存着,是很SB的)。
    c)缓存真正需要的数据。不要觉外存是无限的,所以就可以什么都存,要知道,多则繁,繁则乱。曾经有一同事,每天存几百MB的用户数据(所有用户的性别、age、联系方式等等),而PM需要的只是一个每日数户的活跃数据报表,于是最后改为缓存每天的用户分析报表数据即可(才10几KB)。
    d)给缓存文件加密。最简单就是去掉文件的扩展名,这也算加密,当然,你可以把服务端文件加密,然后在内存中解密。这就看项目的需求而定,我的经验也不足,一般就是改改扩展名之类的。

    三、内存缓存策略
    内存缓存策略是为了应对更加高效的缓存,对于不是频烦更新的文件数据,就可以缓存在内存中,但是有以下注意事项:

    a)内存的I/O,弱引用。弱引用可以让JVM更加合理、自主的回收。
    b)内存缓存的 key 也必须唯一,可以参考文件缓存 key 策略。
    c)提供一个内存缓存刷新的接口。虽然内存缓存本身的生命周期就较短,但它必竟是最上层的用户数据,所以设计时提供一个UI刷新接口,是可以考虑的。

    Android中ListView的addFooterView不显示的问题                                 

    mListView.addFooterView(btn_more, null, false);
    mListView.setAdapter(mBlogListAdapter);

    把addFootView放在setAdapter之前就可解决。

    Android自动弹出软键盘                                                              

    在onCreate中加入:

    // 自动调出软键盘
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }, 200);

    我是天王盖地虎的分割线                                                             

  • 相关阅读:
    Kibana
    Filebeat使用
    leetcode刷题笔记七十三题 矩阵置零
    leetcode刷题笔记七十二题 编辑距离
    leetcode刷题笔记七十一题 简化路径
    leetcode刷题笔记七十题 爬楼梯
    leetcode刷题笔记六十九题 X的平方根
    python 冒泡算法
    hive 函数
    Task07:类、对象与魔法方法(3天)
  • 原文地址:https://www.cnblogs.com/yydcdut/p/3904516.html
Copyright © 2020-2023  润新知