--如何处理android多线程安全
不要堵塞UI线程,不在主线程中做耗时操作的处理,可以开启子线程去执行耗时操作
--如何对性能优化,从哪几个方面进行
1、布局优化
使用relativelayout替代linearlayout减少布局的层级
通过include标签对布局进行复用,一般配合merge标签使用(merge标签可以去重)
使用viewstub标签实现按需加载布局文件
2、内存优化
bitmap优化 ,大量的图片会造成内存占用过高 ,可能会导致OOM问题,可以对图片进行缓存处理和适当的进行图片压缩显示
避免写出内存泄露的代码,如静态变量导致的内存泄露 (被声明的静态的变量引用了该activity,因此无法正常销毁)、单例模式导致的内存泄露(activity被单例模式所持有,因此activity的对象无法被即使释放)
小技巧:
对常量使用static修饰符、尽量使用视图缓存、使用静态方法、减少不必要的对象、尽量不要使用枚举、避免使用IOC框架
还可以通过一些分析工具,比如MAT来找出潜在的内存泄露的地方从而解决
3、响应速度优化
避免在主线程中做耗时操作,将耗时操作放到子线程中去执行
4、线程优化
使用线程池,它可以重用内部的线程,从而避免了线程的创建和销毁所带来的性能开销,
同时它还能有效的控制线程池的最大并发数,避免大量的线程因抢占系统资源,从而导致的阻塞现象的发生
--handler的机制原理
andriod提供了 Handler 和 Looper 来满足线程间的通信。Handler 先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(Message Exchange)。
1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列)。2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;或者接收Looper从Message Queue取出)所送来的消息。
- Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。
---pulltorefresh原理分析
http://blog.csdn.net/birdsaction/article/details/44831737
--android-Ultra-Pull-To-Refresh 源码解析
http://a.codekk.com/detail/Android/Grumoon/android-Ultra-Pull-To-Refresh%20源码解析
--volley源码解析
http://a.codekk.com/detail/Android/grumoon/Volley%20源码解析
--Android网络请求中页面关闭了应该怎么处理
解决方案:http://www.zhihu.com/question/38837116/answer/78745708
http://blog.csdn.net/carlos1992/article/details/50420335
ctivity里面启动了网络请求,而在这个网络请求还没返回结果的时候,Activity被结束了,此时如果继续使用其中的Context等,除了无辜的浪费CPU,电池,网络等资源,有可能还会导致程序crash,所以,我们需要处理这种一场情况。。
说白了,这个问题的关键是在网络线程请求还未返回时,用户结束了这个网络线程的上下文activity后,如何禁止此时网络返回调用刷新UI的网络回调的问题。以下是解决办法:1.如果是通过AsyncTask<>进行的网络请求,那么,你一般是在onPostExecute()方法中进行回调接口的调用。如果是这样的话,只需要使用AsyncTask自带的cancel()方法就可以了,这个方法的调用就放在上下文activity的onStop()方法内。这个方法调用后,会使调用该方法的Asynctask对象isCanceld()方法返回true,且在doInBackground后不调用onPostExecute()而去调用onCancel()方法。剩下的就不用细说了,如果有不懂得话,欢迎提问。2.如果没有使用AsyncTask,而是自己开辟线程,自己是用HttpURLConnection实现,那么解决办法是仿照Google自己的网络请求框架Volley,给网络请求类加一个标志位flag,当activity结束的时候置位。而你自己的网络请求类在网络请求结束后调用网络回调的时候对这个标志位进行判定。这样就可以解决以上问题了。
----tcp/ip和http了解多少 ,socket呢 ,以及他们之间的关系
tcp属于传输层 ,ip属于网络层 ,而http属于应用层 (http,即超文本传输协议 )
tcp/ip负责对数据的传递,http则用于将传递的数据识别显示到网页中
socket也是用于通信,实际上它是对tcp/ip的一个封装,提供给了外部一个通信接口
--socket通信使用流程
建立一个Socket对象 ,设置IP和端口 ,然后获取其I/O流
---如何在Activity之间传递Handler
我的做法是在一个公共类中定义一个public static handler对象.跳转时将这个第一个活动的handler句柄交给公共类,进入第二个界面后再从公共类中取出来用.
---android 用handler怎么把消息发送到指定的activity
思路:
1、建立一个继承Application的子类,定义handle属性并创建get和set方法
2、在主activity中为handler赋值
3、在另一个activity通过Application的子类获取handler进行传值
1.在MyAPP中定义属性handlerpackage jason.com;import jason.com.MasterActivity.MyHandler;import android.app.Application;/*** 自己实现Application,实现数据共享* @author jason*/public class MyAPP extends Application {// 共享变量private MyHandler handler = null;// set方法public void setHandler(MyHandler handler) {this.handler = handler;}// get方法public MyHandler getHandler() {return handler;}}2、在主activity 中给MyAPP的属性handler赋值@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mAPP = (MyAPP) getApplication();handler = new MyHandler();tv = (TextView) findViewById(R.id.tv);btn_to = (Button) findViewById(R.id.btn_to);// 设置监听器btn_to.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 设置共享变量mAPP.setHandler(handler);// 启动另一个ActivityIntent intent = new Intent(MasterActivity.this,ToChangeViewActivity.class);startActivity(intent);}});}3、在另一个activity中获取MyAPP中handler进行传值protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.show);mAPP = (MyAPP) getApplication();// 获得该共享变量实例mHandler = mAPP.getHandler();findViewById(R.id.btn_chang).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 发送消息mHandler.sendEmptyMessage(CHANGED);ToChangeViewActivity.this.finish();}});}
---事件分发机制
http://www.tuicool.com/articles/Mra6vmn
dispatchTouchEvent方法用于事件的分发,Android中所有的事件都必须经过这个方法的分发,然后决定是自身消费当前事件还是继续往下分发给子控件处理。
返回true表示不继续分发,事件没有被消费。返回false则继续往下分发,如果是ViewGroup则分发给onInterceptTouchEvent进行判断是否拦截该事件。
onTouchEvent方法用于事件的处理,返回true表示消费处理当前事件,返回false则不处理,交给子控件进行继续分发。
onInterceptTouchEvent是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截
,返回true的时候表示拦截当前事件,不继续往下分发,交给自身的onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的(iOS可以)。
---多线程并发行及解决方式
同一个程序有多个线程在同一时间段同时处理
以下典型的单例模式的写法,不是线程安全的 ,在多线程的环境,可能会产生一个以上的实例对象
class Singleton { 2privatestatic Singleton obj; 3 4private Singleton() { 5 } 6 7publicstatic Singleton getInstance() { 8if (obj == null) 9 obj = new Singleton();10return obj;11 }12 }
之所以会出现我们不希望的情况 是因为在第一个线程在判断了if(obj==null)之后 准备去构造对象(但是还没有构造)的时候、第二个线程调用了方法、并判断obj是否等于null、此时因为第一个线程还没有构造对象、所以第二个线程也进入了if语句块内、因此 出现了可能会构造两个不同的对象
解决方式 :
在JDK1.5之前(不包括1.5)synchronized关键字来保证例子中单例模式的正确性、即这样定义单例模式
class Singleton { 2privatestatic Singleton obj; 3 4private Singleton() { 5 } 6 7publicsynchronizedstatic Singleton getInstance() { 8if (obj == null) 9 obj = new Singleton();10return obj;11 }12 }
---tcp和udp的区别
TCP是面向连接的,虽然说网络的不安全不稳定特性决定了多少次握手都不能保证连接的可靠性,但TCP的三次握手在最低限度上(实际上也很大程度上保证了)保证了连接的可靠性;
而UDP不是面向连接的,UDP传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,当然也不用重发,所以说UDP是无连接的、不可靠的一种数据传输协议。
简单的说就是:tcp是面向连接的,安全性高,速度较慢 ;udp不是面向连接的 ,安全性较低 ,但速度快