未知账号

明天的一切都是未知的!


  • 首页

  • 归档

  • 标签

经验之谈

发表于 2017-07-19

android 面试答案:

一面

1.ANR 具体产生的类型有哪些,具体说下其产生的最大超时时间。

  • KeyDispatchTimeout(5 seconds) –主要类型:
    按键或触摸事件在特定时间内无响应

  • BroadcastTimeout(10 seconds):
    BroadcastReceiver在特定时间内无法处理完成

  • ServiceTimeout(20 seconds) –小概率类型:
    Service在特定的时间内无法处理完成

2.多线程多点下载的过程

3.http协议的理解和用法

  • HTTP是一个基于请求与响应模式的、无状态的、应用层的协议,属于应用层的面向对象的协议,常基于TCP的连接方式

  • 具备以下特点

    • 1.支持客户/服务器模式。
    • 2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
    • 3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
    • 4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
    • 5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
  • URL格式以及对应的含义

    • 格式 http://host[":"port][abs_path]
    • http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用缺省端口80;abs_path指定请求资源的URI;如果URL中没有给出abs_path,那么当它作为请求URI时,必须以“/”的形式给出,通常这个工作浏览器自动帮我们完成。
  • http 请求

    • http请求由三部分组成,分别是:请求行、消息报头、请求正文
  • http 响应

    • HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文
  • 利用telnet观察http协议的通讯过程
    • 实验目的及原理
      • 利用MS的telnet工具,通过手动输入http请求信息的方式,向服务器发出请求,服务器接收、解释和接受请求后,会返回一个响应,该响应会在telnet窗口上显示出来,从而从感性上加深对http协议的通讯过程的认识。
  • http协议的安全
    • HTTP本身并不提供安全,然而通过在传输层和应用层中使用安全套接层(SSL)可以使HTTP运行在安全的环境下,即HTTPS,HTTPS可以提供保密性,客户和服务器鉴别以及数据的完整性。
    • SSL的设计时为了给应用层生成的数据提供安全以及压缩服务,一般来说SSL能接收来自任何应用层协议的数据,但最多情况下这个应用层的协议就是HTTP,SSL对应用层传来的数据提供多种服务:
      • 分片:SSL把数据划分为长度小于或者等于2的14次字节的数据分片
      • 压缩:数据分片通过使用一种由客户端和服务器协商好的无损压缩方式进行压缩,这个服务是可选的。
      • 报文完整性:为了保护数据的完整性,SSL使用密钥散列函数来创建MAC。
      • 保密:为了提供保密性,原始的数据和MAC一起用对称密钥加密技术来加密。
      • 组帧:先在被加密的有效载荷上添加一个首部,然后再把这个恶有效载荷传递给可靠的运输层协议。

4.安卓如何实现多线程并解决线程并发问题

继承Thread类,重写run函数方法:

class xx extends Thread{
    public void run(){
        Thread.sleep(1000);    //线程休眠1000毫秒,sleep使线程进入Block状态,并释放资源
    }
}
xx.start();    //启动线程,run函数运行

实现Runnable接口,重写run函数方法:

Runnable run =new Runnable() {
    @Override
    public void run() {

    }
}

实现Callable接口,重写call函数方法:

Callable call =new Callable() {
    @Override
    public Object call() throws Exception {
        return null;
    }
}
  • AsyncTask
  • Handler + Looper
  • ThreadPool
  • 同步(Synchronized),易变(volatile),内存模型

5.你知道的数据结构有哪些,说下具体实现机制

  • Map
  • List
  • 栈/队列
  • 树
  • 图

360面试题

发表于 2017-07-19

360面试题

  • post 和 get 的区别?
  • 多线程如何进行数据交互?
  • 多进程如何进行数据交互?
  • 如何实现多线程?
  • 线程和进程的区别?
  • http 和 https的区别?https是如何在http上建成的?
  • udp 和 tcp 的区别?
  • http属于网络传输协议的哪一层?
  • ThreadHandler 是什么?
  • 单例模式怎么实现?builder 模式的优势?
  • MVC, MVP, MVVM的区别?
  • ImageLoader的实现原理,和Glide比较各自的优缺点?
  • View的绘制
  • 如何实现一个自定义的View?
  • 实现快排
  • native 和 js 如何进行数据交互?
  • 热修复技术用的是什么?
  • GitHub博客的搭建过程?
  • 弹幕问题是如何修复的?
  • 内存泄漏可能发生的情况以及发生后如何定位?
  • 模拟一个View的点击事件获取网络数据并展示的过程
  • 用过哪些开源框架?百度SDK如何接入自己的项目的?
  • 在项目中充当的角色?干了些什么事?
  • service 和 activity是否在同一个进程中?如何新建一个进程?
  • 四大组件有哪些?
  • 聊天如何实现的?用的第三方框架还是自己实现的?
  • GreenDao 和 Sqlite

杂记

发表于 2017-06-29

确定项目中是否有内存泄漏

Android studio 查看:Memory Monitor
命令行模式:adb shell dumpays meminfo 包名 -d

  • ddd

反射机制

发表于 2017-06-19

反射机制的实现

反射机制:代码示例:

  • 被引用类

    package com.zcdog.dogtv.manager.interval;
    
    import com.zcdog.dogtv.entity.RedDotEntity;
    import com.zcdog.dogtv.model.RedDotModel2;
    import com.zcdog.dogtv.view.user.RedDotViewAdapter;
    import com.zcdog.util.info.android.Logger;
    import com.zcdog.zchat.ui.view.ZChatRedDotView;
    
    /**
     * 警告:该类被 ZChat 模块通过反射调用,改动需谨慎
     * <p/>
     * Created by Ivey on 2016/5/21.
     */
    public class RefreshFriendHallRedDotHelper {
    
        private static final String TAG = "RefreshFriendHallRedDotHelper";
    
        public static void refreshVisitorsRedDotStatus(Boolean show) {
            if (RedDotModel2.redDotCache != null && RedDotModel2.redDotCache.getMap() != null) {
                RedDotEntity redDotEntity = RedDotModel2.redDotCache.getMap().get(RedDotModel2.ZCHAT_VISITOR_TYPE);
                if (redDotEntity != null) {
                    Logger.d(TAG, "更新 最近访客 的红点状态");
                    if (show) {
                        redDotEntity.setNumber(0);
                    }
                    redDotEntity.setShow(show);
                    RedDotModel2.saveCache();
                }
            }
        }
    
        public static void refreshMsgRedDotStatus(Integer number) {
            if (RedDotModel2.redDotCache != null && RedDotModel2.redDotCache.getMap() != null) {
                RedDotEntity redDotEntity = RedDotModel2.redDotCache.getMap().get(RedDotModel2.ZCHAT_MESSAGE_ROOT_TYPE);
                if (redDotEntity != null) {
                    Logger.d(TAG, "更新 未读消息 的红点状态");
                    if (number <= 0) {
                        redDotEntity.setShow(false);
                    } else {
                        redDotEntity.setNumber(number);
                        redDotEntity.setShow(true);
                    }
                }
            }
        }
    
        public static void setRedDotIcon(ZChatRedDotView redDotView) {
            if (RedDotModel2.redDotCache != null && RedDotModel2.redDotCache.getMap() != null) {
                RedDotEntity redDotEntity = RedDotModel2.redDotCache.getMap().get(redDotView.getType());
                if (redDotEntity != null) {
                    redDotEntity.setRedDotIcon(new RedDotViewAdapter(redDotView));
                }
            }
        }
    
    }
    
  • 引用类:

    package com.zcdog.zchat.manager;
    
    import com.zcdog.zchat.ui.view.ZChatRedDotView;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * SmartLocker 模块中 RefreshFriendHallRedDotHelper 类的映射
     * <p/>
     * Created by Ivey on 2016/5/21.
     */
    public class ZChatRefreshFriendHallRedDotHelper {
        private static final String TAG = "ZChatRefreshFriendHallRedDotHelper";
    
        private static final String CLASS_NAME = "com.zcdog.dogtv.manager.interval.RefreshFriendHallRedDotHelper";
    
        public static void refreshVisitorsRedDotStatus(boolean show) {
            try {
                Class RefreshFriendHallRedDotHelper = Class.forName(CLASS_NAME);
                Method refreshVisitorsRedDotStatus = RefreshFriendHallRedDotHelper.getMethod("refreshVisitorsRedDotStatus", Boolean.class);
                refreshVisitorsRedDotStatus.invoke(null, show);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
        public static void refreshMsgRedDotStatus(int number) {
            try {
                Class RefreshFriendHallRedDotHelper = Class.forName(CLASS_NAME);
                Method refreshVisitorsRedDotStatus = RefreshFriendHallRedDotHelper.getMethod("refreshMsgRedDotStatus", Integer.class);
                refreshVisitorsRedDotStatus.invoke(null, number);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
        public static void setRedDotIcon(ZChatRedDotView redDotView) {
            try {
                Class RefreshFriendHallRedDotHelper = Class.forName(CLASS_NAME);
                Method refreshVisitorsRedDotStatus = RefreshFriendHallRedDotHelper.getMethod("setRedDotIcon", ZChatRedDotView.class);
                refreshVisitorsRedDotStatus.invoke(null, redDotView);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
    }
    
  • 自己手动总结如下:

     public class ATest(){
         private static final TAG = "ATest";
    
         public static void functionOne(Boolean ValueA){
              //do something
         }
    
     public static void functionTwo(Integer ValueB){
              //do something
         }
    }
    
    public class BTest(){
         private static String TAG = "BTest";
         private static final String CLASS_NAME = "包名.ATest"
    
     public static void functionOne(boolean a){
          try {
            Class ATest= Class.forName(CLASS_NAME);
            Method functionOne= ATest.getMethod("functionOne", Boolean.class);
            functionOne .invoke(null, a);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
     }
    
 public static void functionTwo(int b){
          try {
            Class ATest= Class.forName(CLASS_NAME);
            Method functionTwo= ATest.getMethod("functionTwo", Integer.class);
            functionTwo .invoke(null, b);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
     }
}

Toast的封装

发表于 2017-06-19

Toast的封装

public class Util {

private static Toast toast;
public static void showToast(Context context, String content){
          if(toast == null){
                    toast = Toast.makeText(context,content,Toast.LENGTH_SHORT);
               } else {
                toast.setText(content );
               }
           toast.show();
     }
}

OKHttp

发表于 2017-06-19
  • OKHttp 的同步get

    private final OkHttpClient client = new OkHttpClient();
    public void execute() throw Exception{
        Request request = new Request.Builder()
                .url("http://publicobject.com/helloworld.txt")
                .build();
    
        Response response = client.newCall(request).execute();
        if(response.isSuccessful()){
            //do something
        }
    }
    
  • OKHttp 的异步get

    private final OkHttpClient client = new OkHttpClient();
    public void enqueue(){
        Request request = new Request.Builder()
                .url()
                .builder();
    
        client.newCall(request).enqueue(new Callback(){
    
            @Override
            public void onFailure(){
                //do  something
            }
    
            @Override
            public void onResponse(Response response) throw IOException{
    
                if(response.isSuccessful()){
                    //do something
                }
            }
    
        });
    }
    

Fragment数据保存

发表于 2017-06-19

Fragment 数据保存

采用 Fragment.setArguments(Bundle bundle) 方式来保存原有数据不丢失。

示例

  • FragmentA中的方法

    public static void setArguments(Fragment fragment, Serializable serializable, String describle, int index){
         Bundle bundle = new Bundle();
         bundle.putSerializable(BUNDLE_SERIALIZABLE, serializable);
         bundle.putString(BUNDLE_DESCRIBLR, describle);
         bundle.putInt(BUNDLE_INDEX, index);
         fragment.setArguments(bundle);
    }
    
  • 在ActivityB 中调用:

    FragmentA.setArguments(fragment, serializable, "name", 10);
    

代码小结

发表于 2017-06-19
  • 过滤器可以设置优先级:

    IntentFilter filter = new IntentFilter();
    filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
    
  • 获取随机函数

    private static int getRandom(int sumWeight) {
        return (int) Math.round(Math.random() * sumWeight);
    }
    
  • Bundle 的传值使用方法:

    Bundle bundle = new Bundle();
    bundle.putString("a", "sub");
    bundle.putString("b", "let");
    
    Intent intent = new Intent(this, activityA.class);
    intent.putExtra("all", bundle);
    startActivity(intent);
    
  • 代码设置屏幕竖屏:

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    
  • 设置延时的handler:

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            DaemonServiceManager.startDaemonService(LauncherActivity.this);
            startMainActivity(true);
            handler.sendEmptyMessageDelayed(FINISH_WHAT, FINISH_INTERVAL_TIME);
        }
    }, intervalTime);
    
  • 在Android里面

    view = new ImageView(context);
    view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    view.setBackgroundResource(R.drawerable.**);
    

中,资源文件只能是图片等资源文件,布局文件是不能这样写的,如果要嵌入布局,如下:

view =  View.inflate(Context context, R.layout.**, null);

ImageLoader

发表于 2017-06-19

ImageLoader相关的内容:

  • 基本格式

    public class MyAppliction extends Application {
    
        @Override
        public void onCreate() {
    
            super.onCreate();
    
            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
            ....
            .build();
    
            ImageLoader.getInstance().init(config);
    
        }
    }
    
  • 没有把图片缓存在sd卡中的实现方式

    public class MyAppliction extends Application {
    
        @Override
        public void onCreate() {
    
        super.onCreate();
    
        //对config 的定义与实现
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                                    .threadProirity(Thread.NORM_PROIRITY - 2)
                                    .denyCacheImageMultipleSizeInMemory()
                                    .discCacheFileNameGenerator(new Md5FileNameGenerator())
                                    .tasksProcessingOrder(QueueProcessingType.LIFO)
                                    .enableLogging()
                                    .build();
        ImageLoader.getInstance().init(config);
    
        }
    }
    
  • 将图片缓存在SD卡中的实现方式

    public class MyAppliction extends Application {
    
        @Override
        public void onCreate() {
    
        super.onCreate();
    
        //对config 的定义与实现
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheInMemory()
                .cacheOnDisc()
                .build();
        ImageLoaderConfiguration config2 = new ImageLoaderConfiguration.Builder(context)
                .defaultDisplayImageOptions(defaultOptions)
                .threadProirity(Thread.NORM_PROIRITY - 2)
                .denyCacheImageMultipleSizeInMemory()
                .discCacheFileNameGenerator(new Md5FileNameGenerator())
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                .enableLogging()//Not necessary in common // 1.8.6包,把这句话删除
                .build();
        ImageLoader.getInstance().init(config2);
        }
    }   
    
  • 图片加载时候,添加监听和加载进度条的代码

    imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener(){
    
        @Override
        public void onLoadingStarted(){
    
        }
    
        @Override
        public void onLoadingFailed(){
    
        }
    
        @Override
        public void onLoadingComplted(){
    
        }
    
        @Override
        public void onLoadingCancelled(){
    
        }//如果不需要加载进度条的话,后面的就可以直接不用写
        , new ImageLoadingProgressListener(){
            @Override
            public void onProgressUpdate(String imageUrl, View view, int current, int total){
                //在这里更新 ProgressBar 的进度信息
            }
        }
    })
    

recycleView的使用

发表于 2017-06-19
  • recycleView常用的几种样式布局:
* LinearLayoutManager 线性布局管理器      (ListView效果)
* GridLayoutManager    网格布局管理器    (GridView效果)
* StaggeredGridLayoutManager  瀑布流管理器
  • 关于recycleview 的使用方法

首先自定义一个recycleViewAdapter 如下:

package com.example.think.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.think.myapplication.R;

import java.util.ArrayList;

/**
* Created by HuangMei on 2016/8/3.
*/
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder>{

    Context context;
    ArrayList<String> arrayList = new ArrayList<>();

    public RecycleViewAdapter(Context context, ArrayList<String> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = View.inflate(context, R.layout.recycler_item, null);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.textView.setText(arrayList.get(position));

        //以下几行是为瀑布流设置高度使用的(备注:如果不是瀑布流的时候不需要添加)
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,100+(int) (Math.random() * 50));
        holder.imageView.setLayoutParams(lp);
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder{
        TextView textView;
        ImageView imageView;

        public ViewHolder(View itemView) {
            super(itemView);

            textView = (TextView) itemView.findViewById(R.id.textView);
            imageView = (ImageView) itemView.findViewById(R.id.imageView);
        }
    }
}

然后在自己的活动里面调用自己的自定义适配器

public class MainActivity extends Activity {

    ArrayList<String> arrayList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView recylcer = (RecyclerView) findViewById(R.id.recyclerView);

        //ListView效果的 LinearLayoutManager
//        LinearLayoutManager mgr = new LinearLayoutManager(this); //备注:listview样式和九宫格样式公用
//        //VERTICAL纵向,类似ListView,HORIZONTA 横向,类似Gallery 
//        mgr.setOrientation(LinearLayoutManager.HORIZONTAL);//备注:也可以是VERTICAL

        //GridLayout 3列
//        GridLayoutManager mgr=new GridLayoutManager(this,3);

        StaggeredGridLayoutManager mgr = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);

        recylcer.setLayoutManager(mgr);
        //设置适配器
        recylcer.setAdapter(new RecycleViewAdapter(this, setData(10)));
    }

    ArrayList<String> setData(int n){
        for(int i = 0; i < n; i ++){
            arrayList.add(i + "" + i + "" + i + "" + i + "" + i);
        }
        return arrayList;
    }
}
1234
HM

HM

懂的or不懂的,我都记录在这里

36 日志
3 标签
GitHub Twitter Weibo DouBan ZhiHu FriendLink
© 2017 HM
由 Hexo 强力驱动
主题 - NexT.Muse