一.Activity 和 Fragment
1)Activity 生命周期
onCreate - onStart - onResume (Activity运行)- onPause - onStop - onDestroy(Activity销毁)
2)Fragment生命周期
onAttach - onCreate - onCreateView - onViewCreated - onActivityCreated - onStart - onResume
3)Activity和Fragment ,Fragment和 Fragment 是如何通信的
A.Fragment和Activity之间通信
https://blog.csdn.net/lmj623565791/article/details/37992017
Activity访问Fragment
1、使用fragment标签直接构建的Fragment
我们在所依附的Activity里可以通过 getFragmentManager()先获取FragmentManager对象
再通过调用FragmentManager对象的 findFragmentByTag()和findFragmentById()得到Fragment对象
再调用Fragment对象的getView()获取Fragment对应的View对象view
最后再调用View的view.findViewById方法获取或者直接通过Fragment对象调用相关访问属性的方法。
FragmentManager manager = getFragmentManager();
TargetFragment targetFragment = (TargetFragment)manager.findFragmentById(R.id.id_fragment_showpic);
2、动态Java代码构建的Fragment
由于我们add时候会先用代码声明一个Fragment对象,所以我们可以跳过前面的2步,
直接使用Fragment对象的getProperty()方法获取成员,其他的与静态构建Fragment相同
Fragment获取Activity控件
--由于Fragment依附于Activity,属于Activity的一部分,并且拥有自己的View,
所以我们通过getActivity()先得到依附的Activity对应的View,在通过view.findViewById()
MainFragment.java:
public class MainFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view=inflater.inflate(R.layout.fragment_main,null);
Button button= (Button) view.findViewById(R.id.id_tofragment_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView textView=(TextView) getActivity().findViewById(R.id.id_content_edt);
String txt=textView.getText().toString();
Toast.makeText(getActivity(),txt,Toast.LENGTH_LONG).show();
}
});
return view;
}
}
B.Fragment1和 Fragment2
-首先获取到另一个Fragment2对象,然后直接在一个Fragment1中调用另一个Fragment2的public方法
通过宿主Activity获取到FragmentManager,然后在获取到另一个Fragment2的实例
ContentFragment cf = (ContentFragment) getActivity()
.getFragmentManager().findFragmentById(
R.id.content_fg);
cf.showPro(name);
这种方法适于那些我们在布局文件中就已经定义了的Fragment,这种Fragment每个都有id。
可以通过FragmentManager找到,但是如果我们使用了ViewPager,即每个Fragment都是动态添加进来的,
这个时候我们无法通过FragmentManager获得另外一个Fragment的实例
还有使用 广播 和使用接口 都可以实现Fragment之间,Activity和Fragment之间通信
https://blog.csdn.net/u012702547/article/details/49786417
接口实现
Fragment1 和 Fragment2之间通信
--有效的解决在一个Fragment中拿不到另一个Fragment实例的问题,
具体应用场景就是ViewPager中的Fragment之间通信。
-- 1.Fragment1定义一个接口 showPro
public interface showPro {
public void showProByName(String name);
}
-- 2 定义一个变量
private showPro mCallback;
-- 3 在宿主Activity实现这个接口 showPro
public class MainActivity extends Activity implements showPro {
private ContentFragment cf;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getActionBar().hide();
cf = (ContentFragment) getFragmentManager().findFragmentById(
R.id.content_fg);
}
@Override
public void showProByName(String name) {
cf.showPro(name);
}
}
-- 4 当Fragment调用onAttach方法时我们就可以实例化这个接口 showPro
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity != null) {
mCallback = (showPro) activity;
}
}
广播实现
-- 1 不论我们有没有用ViewPager,都可以用广播实现两个Fragment之间的通信,
广播算是这里最灵活的通信方式了,我们看看在左边Fragment1中发送广播:
Intent intent = new Intent("showPro");
intent.putExtra("name", name);
LocalBroadcastManager.getInstance(getActivity())
.sendBroadcast(intent);
-- 2 右边Fragment2中接收广播:
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
.getInstance(getActivity());
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("showPro");
BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String key = intent.getStringExtra("name");
list = map.get(key);
adapter = new ArrayAdapter(getActivity(),
android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
}
};
localBroadcastManager.registerReceiver(br, intentFilter);
4)为什么要用Fragment
Fragment优点
对页面逻辑解耦带来了极大的方便。其拥有自己的生命周期,便于我们来控制和管理页面的状态变化
Fragment可以使你能够将activity分离成多个可重用的组件,每个都有它自己的生命周期和UI。
Fragment可以轻松得创建动态灵活的UI设计,可以适应于不同的屏幕尺寸。从手机到平板电脑。
Fragment是一个独立的模块,紧紧地与activity绑定在一起。可以运行中动态地移除、加入、交换等。
Fragment提供一个新的方式让你在不同的安卓设备上统一你的UI。
Fragment 解决Activity间的切换不流畅,轻量切换。
Fragment 替代TabActivity做导航,性能更好。
Fragment 在4.2.版本中新增嵌套fragment使用方法,能够生成更好的界面效果。
Fragment做局部内容更新更方便,原来为了到达这一点要把多个布局放到一个activity里面,现在可以用多Fragment来代替,
只有在需要的时候才加载Fragment,提高性能。
可以从startActivityForResult中接收到返回结果,但是View不能
二 Service
为什么要用service
Service是用于后台服务的,当应用程序被挂到后台的时候,为了保证应用某些组件仍然可以工作而引入了Service这个概念。
Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,
在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR,
IntentService是什么
IntentService是继承Service的,是为了解决在Service进行耗时操作会引起ANR,引入的
IntentService包含Service的全部特性,包含生命周期
与service不同的是在执行onCreate操作的时候,会内部开启一个线程,去执行耗时操作
IntentService 异步处理服务,新开一个线程,HandlerThread在线程发消息,处理完成后,清理线程,关闭服务
3)生命周期
三 Broadcast
1)本地广播的含义
LocalBroadcastmanager.sendBroadcast(Intent),只在app内传播
四 开源框架
1)EventBus
EventBus是一个消息总线,以观察者模式实现,用于简化程序的组件,县城铜线,可以轻易切换线程,开辟线程
基本使用
1 自定义一个类
2 在接收界面注册
3 发送消息
4 接收消息的界面
5 解除注册
五 原理问题
Java相关
一 JVM内存模型
1 程序计数器(Program Counter Register)
2 Java虚拟机栈(Java Stack)
3 本地方法栈(Native Method Stack)
4 堆(Heap)
5 方法区(Method Area)
二 Android 内存泄露,举例几个容易发生内存泄露的场景;
1)定义
–指程序申请内存后,无法释放已经申请的内存空间2)出现内存泄露的场合及解决方案
–Activity 中handler间断的post消息,会造成activity泄露(
参考 https://www.cnblogs.com/xujian2014/p/5025650.html
https://blog.csdn.net/zheng2186096/article/details/52372294)
https://blog.csdn.net/a910626/article/details/50849760
三
1)子类可以继承父类的静态方法和静态变量么? 子类父类同名静态方法存在“重写”关系么?
–1 . 子类可以继承父类的静态方法和静态变量。因为Static修饰的方法和变量属于类本身,
子类可以访问父类的静态方法和变量,但是前提父类不被Private修饰,对子类是可见的
–2 . 因为Static修饰的方法和变量属于类本身,子类 和 父类中同名的静态变量和方法 都是相互独立的,属
于各自类本身的。不存在重写 呈现多态特性。
2)final 含义,修饰数据,参数 方法 类 的意义?
final修饰数据
– 1 一个永不改变的编译时常量
2 一个在运行时被初始化的值,不希望它被改变
3 final修饰说明它是一个常量,static修饰则强调只有一份
4 final static修饰的基本类型全用大写字母命名,之间用下划线隔开
final 修饰参数
– 可以读取参数,不能修改参数数值
final 修饰方法
– 锁定方法,保证继承类无法覆盖该方法
final 修饰方法
– 不能有子类继承该类
final修饰数据 – 1 一个永不改变的编译时常量
2 一个在运行时被初始化的值,不希望它被改变
3 final修饰说明它是一个常量,static修饰则强调只有一份
4 final static修饰的基本类型全用大写字母命名,之间用下划线隔开
final 修饰参数 –
可以读取参数,不能修改参数数值
final 修饰方法 – 锁定方法,保证继承类无法覆盖该方法 final 修饰方法
– 不能有子类继承该类
3)使用的集合有哪些?
4)多线程并发机制
多线程实现的两种方式:
–通过实现java.lang.Runnale接口
–通过扩展java.lang.Thread类
1.实现Runnable
public interface Runnable {
void run();
}
a.创建一个实现Runnable接口的类,该类的对象是一个Runnable对象
b.创建一个Thread类型的对象,并将Runnable对象作为参数传入到Thread的构造函数中
于是这个Thread对象包含一个 实现了run()方法的Runnable对象
c.调用上一步创建的Thread对象的start方法。
public class RunnableThreadExample implements Runnable {
public int count = 0;
public void run() {
System.out.println("RunnableThread strting");
try {
while(count < 5) {
Thread.sleep(500);
count++;
}
} catch(InterruptedException exc) {
System.out.println("RunnableThread interrupted");
}
System.out.println("RunnThread terminating");
}
}
public static void main(String[] args) {
RunnableThreadExample instance = new RunnableThreadExample;
Thread thread = new Thread(instance);
thread.start();
while(instance.count !=3) {
try{
Thread.sleep(250);
} catch (InterruptedException exc) {
exc.printStackTrace();
}
}
}
2 扩展Thread类
5)死锁
a.定义
–第一个线程在等待第二个线程持有的某个资源,而第二个线程又在等待第一个线程持有的对象资源
(或者两个以上县城形成的类似情形)。由于每个线程都在等待其他线程释放资源,导致每个线程都会
一直等下去,于是这些线程就陷入了死锁。b.死锁产生的四个条件
– 1 互斥
某个时刻只有一个线程能访问某个资源
2 持有并等待
一个进程已经持有某一资源,不用释放当前拥有的资源,就能要求获得更多资源
3 没有抢占
一个进程不能强制另一个进程释放资源
4 循环等待
两个或两个以上进程形成循环链,每个进程都在等待循环链中的另一个进程持有的资源
6)网络相关
7)常用设计模式
数据结构
一 链表
1)如何判断单链表相交