1.Activity屏幕方向与显示方式与屏幕旋转
//代码设置横竖屏,也可以在menifest中设置
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//横屏
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
<activity android:name=".TimeActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
<activity android:name=".MenuActivity" android:screenOrientation="landscape" />
//去掉标题栏和通知栏,在setContentview之前设置
//设置全屏模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//去除标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
//activity窗口化运行
".TextSwitcherActivity" android:theme="@android:style/Theme.Dialog" />
//屏幕旋转的时候,执行了onCreate,说明activity被重建了,所以在屏幕旋转时候,要保存状态,在旋转之后再把数据恢复
//屏幕旋转时会触发(也就是说异常销毁activity)
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("key1","valuess");
}
//可以在onCreate中恢复数据
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState !=null) {
String str = savedInstanceState.getString("key1");
}
setContentView(R.layout.activity_time);
}
//可以在onCreate中恢复数据,也可以在onRestoreInstanceState中恢复数据
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
//也可以旋转屏幕的时候,不让它重新创建
".TextSwitcherActivity"
android:configChanges="keyboard|screenSize|orientation" />//加上这个属性后,旋转屏幕的时候不会重新创建,会调用onContentChanged这个方法这个方法一般不用做什么操作
public void onContentChanged() {
super.onContentChanged();
}
2.SharedPreferences 在onPause中保存,在onResume中恢复数据
package com.recycler.zx.zxrecyclerview;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class SharePreferenceActivity extends AppCompatActivity {
private SharedPreferences sf;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share_preference);
//获取当前程序SharedPreferences
sf = getSharedPreferences("share_all", Context.MODE_PRIVATE);
}
//进行还原数据
@Override
protected void onResume() {
super.onResume();
String result = sf.getString("key1","");
}
//在该时间方法里来存储数据
@Override
protected void onPause() {
super.onPause();
SharedPreferences.Editor editor = sf.edit();
editor.putString("key1","values1");
editor.commit();
editor.remove("key1");//根据key删除
editor.clear();//清楚所有的SharedPreferences
}
}
3.Intent
//直接查找法(通过组件名称)
Intent intent = new Intent();
ComponentName componentName = new ComponentName(this,MenuActivity.class);
intent.setComponent(componentName);
/用的最多的//用的最多的
Intent intent = new Intent();
intent.setClass(this,MenuActivity.class);
startActivity(intent);
4.创建服务service
android studio 可以直接右键创建一个service,(会自动在menifest中注册)
<service
android:name=".Service.MyService"
android:enabled="true"
android:exported="true">service>
5.广播
开启启动广播,先自动创建一个
StartupReceiver
".BroadcastReceiver.SystemBroadcast.StartupReceiver"
android:enabled="true"
android:exported="true">
"android.intent.action.BOOT_COMPLETED">
"android.permission.RECEIVE_BOOT_COMPLETED" />
检测网络状态:
package com.recycler.zx.zxrecyclerview.BroadcastReceiver.SystemBroadcast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;
public class InternetReceiver extends BroadcastReceiver {
public InternetReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getActiveNetworkInfo();
if(info !=null) {
String name = info.getType()+"";
Toast.makeText(context,"---"+name,Toast.LENGTH_SHORT).show();
}
}
}
6.fragment的两种添加方式
//xml文件添加
package com.recycler.zx.zxrecyclerview.fragments;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.recycler.zx.zxrecyclerview.R;
public class FragmentsActivity extends AppCompatActivity {
TitleFragment titleFragment;
ContentFragment contentFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragments);
titleFragment = (TitleFragment) getFragmentManager().findFragmentById(R.id.fragment_title);
contentFragment = (ContentFragment) getFragmentManager().findFragmentById(R.id.fragment_content);
}
}
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.recycler.zx.zxrecyclerview.fragments.FragmentsActivity">
"0dp"
android:id="@+id/fragment_title"
android:layout_weight="1"
android:name="com.recycler.zx.zxrecyclerview.fragments.TitleFragment"
android:layout_height="match_parent"/>
"@+id/fragment_content"
android:layout_width="0dp"
android:layout_weight="3"
android:name="com.recycler.zx.zxrecyclerview.fragments.ContentFragment"
android:layout_height="match_parent"/>
//fragment可以直接右键新建
package com.recycler.zx.zxrecyclerview.fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.recycler.zx.zxrecyclerview.R;
/**
* Created by zx on 2015/12/17.
*/
public class TitleFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.layout_title,container,false);
return v;
}
}
package com.recycler.zx.zxrecyclerview.fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.recycler.zx.zxrecyclerview.R;
/**
* Created by zx on 2015/12/17.
*/
public class ContentFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.layout_content,container,false);
return v;
}
}
//代码添加
package com.recycler.zx.zxrecyclerview.fragments;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.recycler.zx.zxrecyclerview.R;
public class FragmentsCodeActivity extends AppCompatActivity {
ContentFragment contentFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragments_code);
addContentLayout();
}
//t通过代码添加fragment
private void addContentLayout() {
FragmentManager fm = getFragmentManager();
//开启一个事务
FragmentTransaction ft = fm.beginTransaction();
contentFragment = new ContentFragment();
//添加fragment
ft.add(R.id.frameLayout_content,contentFragment);
//ft.remove();
// ft.replace();替换,先删除,再添加
ft.commit();//提交事务
}
}
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.recycler.zx.zxrecyclerview.fragments.FragmentsCodeActivity">
"0dp"
android:id="@+id/fragment_title"
android:layout_weight="1"
android:name="com.recycler.zx.zxrecyclerview.fragments.TitleFragment"
android:layout_height="match_parent"/>
"@+id/frameLayout_content"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="match_parent"/>
7.Fragment出入栈操作和 官方推荐传递参方法
package com.recycler.zx.zxrecyclerview.fragments;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import com.recycler.zx.zxrecyclerview.R;
public class PopBackTaskActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pop_back_task);
}
public void one(View v){
PopBacksFragment popBacksFragment = PopBacksFragment.getInstance("one");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.ft_content,popBacksFragment);
//把当前fragment添加到Activity栈
ft.addToBackStack(null);
ft.commit();
}
public void two(View v){
PopBacksFragment popBacksFragment = PopBacksFragment.getInstance("two");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.ft_content,popBacksFragment);
//把当前fragment添加到Activity栈
ft.addToBackStack(null);
ft.commit();
}
//点返回键的时候,判断栈中是否存在,存在就做出栈操作
//比activity性能要高一些
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) {
//如果返回栈里面没有了
if(getFragmentManager().getBackStackEntryCount() == 0) {
finish();
} else {
getFragmentManager().popBackStack();//出栈,不进行退出操作
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.recycler.zx.zxrecyclerview.fragments.PopBackTaskActivity">
package com.recycler.zx.zxrecyclerview.fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.recycler.zx.zxrecyclerview.R;
/**
* A simple {@link Fragment} subclass.
*/
public class PopBacksFragment extends Fragment {
private static final String TITLE = "title";
private String title ;
public PopBacksFragment(){}
// public PopBacksFragment(String title) {
// this.title =title;
// }
//fragment的标准传参数方法,这样传参数的时候屏幕旋转数据不会消失,(并且Fragment是不允许使用有参的构造方法的)
public static PopBacksFragment getInstance(String title){
PopBacksFragment pf = new PopBacksFragment();
Bundle bundle = new Bundle();
bundle.putString(TITLE,title);
pf.setArguments(bundle);
return pf;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_pop_backs, container, false);
TextView tvPop = (TextView) v.findViewById(R.id.tv_pop);
tvPop.setText(getArguments().getString(TITLE));
return v;
}
}
8.fragment和activity交换数据
//把数据从MenuFragment 传递到 MainFragment
package com.recycler.zx.zxrecyclerview.fragments.fragmentAndActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.recycler.zx.zxrecyclerview.R;
public class FramentAndActivity extends AppCompatActivity implements MenuFragment.MyMenuListener {
private MenuFragment menuFragment;
private MainFragment mainFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frament_and);
menuFragment = (MenuFragment) getFragmentManager().findFragmentById(R.id.menu_fragment);
mainFragment = (MainFragment) getFragmentManager().findFragmentById(R.id.main_frament);
}
@Override
public void changeValue(String value) {
mainFragment.setTvValue(value);
}
}
package com.recycler.zx.zxrecyclerview.fragments.fragmentAndActivity;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.recycler.zx.zxrecyclerview.R;
/**
* A simple {@link Fragment} subclass.
*/
public class MenuFragment extends Fragment {
private MyMenuListener mMyMenuListener;
public MenuFragment() {
// Required empty public constructor
}
@Override
public void onAttach(Activity context) {
super.onAttach(context);
mMyMenuListener = (MyMenuListener) context;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_menu, container, false);
Button news = (Button) v.findViewById(R.id.news);
Button music = (Button) v.findViewById(R.id.music);
news.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMyMenuListener.changeValue("news");
}
});
music.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMyMenuListener.changeValue("music");
}
});
return v;
}
//定义一个回调接口,要求宿主(包含它的Activity)去实现它
public static interface MyMenuListener{
public void changeValue(String value);
}
}
package com.recycler.zx.zxrecyclerview.fragments.fragmentAndActivity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.recycler.zx.zxrecyclerview.R;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* A simple {@link Fragment} subclass.
*/
public class MainFragment extends Fragment {
@Bind(R.id.tv_value)
TextView tvValue;
public MainFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main, container, false);
ButterKnife.bind(this, view);
return view;
}
public void setTvValue(String value){
tvValue.setText(value);
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
}
8.PreferenceFragment 实现设置用户习惯操作
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="声音设置">
<CheckBoxPreference
android:key="checkbox_preference"
android:title="是否打开声音"
android:summary="打开声音后可以自动开启音乐" />
PreferenceCategory>
<PreferenceCategory
android:title="城市">
<EditTextPreference
android:key="edittext_preference"
android:title="昵称"
android:summary="请输入昵称:"
android:dialogTitle="昵称哇:" />
<ListPreference
android:key="list_preference"
android:title="城市名称"
android:summary="请选择城市"
android:entries="@array/city"
android:entryValues="@array/city"
android:dialogTitle="城市名称哇:" />
<PreferenceScreen
android:title="百度"
android:summary="访问">
<intent android:action="android.intent.action.VIEW"
android:data="http://www.android.com" />
PreferenceScreen>
PreferenceCategory>
PreferenceScreen>
2.String.xml中可能需要使用
<string-array name="city">
<item>北京item>
<item>上海item>
<item>关注item>
<item>杭州item>
string-array>
resources>
3. PrefsFragmentextends PreferenceFragment
package com.recycler.zx.zxrecyclerview.fragments.preference;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import com.recycler.zx.zxrecyclerview.R;
public class PrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.my_preference);
}
}
9.ActionBar
package com.recycler.zx.zxrecyclerview.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.ShareActionProvider;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.recycler.zx.zxrecyclerview.MenuActivity;
import com.recycler.zx.zxrecyclerview.R;
import com.recycler.zx.zxrecyclerview.TimeActivity;
import com.recycler.zx.zxrecyclerview.fragments.ContentFragment;
import com.recycler.zx.zxrecyclerview.fragments.TitleFragment;
public class MyActionBarActivity extends AppCompatActivity implements ActionBar.TabListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_action_bar);
ActionBar actionBar = getSupportActionBar();
// actionBar.hide();//隐藏actionbar
actionBar.setHomeButtonEnabled(true);
startActivity(new Intent(this, MenuActivity.class));
//导航条
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);//标题栏不显示
//添加选项卡
ActionBar.Tab tab = actionBar.newTab()
.setText("美女")
.setTabListener(this);
actionBar.addTab(tab);
tab = actionBar.newTab()
.setText("新闻")
.setTabListener(this);
actionBar.addTab(tab);
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.getCallState();
telephonyManager.listen(new PhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE );
}
@Override
public boolean onCreateOptionsMenu( Menu menu) {
getMenuInflater().inflate(R.menu.menu_context, menu);
//搜索
MenuItem mi = menu.findItem(R.id.yellow);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(mi);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(MyActionBarActivity.this,"---"+query,Toast.LENGTH_SHORT).show();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
//分享
MenuItem mi2 = menu.findItem(R.id.share);
ShareActionProvider provier = (ShareActionProvider)MenuItemCompat.getActionProvider(mi2);
provier.setShareIntent(getDefaultIntent2());
return true;
}
private Intent getDefaultIntent(){
Intent in = new Intent(Intent.ACTION_SEND);
in.setType("image/*");
return in;
}
private Intent getDefaultIntent2(){
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT,"这是。。");
startActivity(intent);
return intent;
}
//导航条
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Toast.makeText(this,tab.getText(),Toast.LENGTH_SHORT).show();
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
//电话服务
class PhoneStateListener extends android.telephony.PhoneStateListener{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_RINGING :
Toast.makeText(MyActionBarActivity.this,"正在响铃",Toast.LENGTH_SHORT).show();
break;
case TelephonyManager.CALL_STATE_IDLE :
Toast.makeText(MyActionBarActivity.this,"正在响铃",Toast.LENGTH_SHORT).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK :
Toast.makeText(MyActionBarActivity.this,"正在响铃",Toast.LENGTH_SHORT).show();
break;
}
}
}
}
public class MenuActivity extends AppCompatActivity {
@Bind(R.id.tv_bg)
TextView mTvBg;
@Bind(R.id.tv_popmenu)
TextView mTvPopmenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
ButterKnife.bind(this);
ActionBar actionBar = getSupportActionBar();
// actionBar.hide();//隐藏actionbar
actionBar.setDisplayHomeAsUpEnabled(true);//设置当前的activity
1.handler发送一个消息(Message)到消息队列(MessageQueue)
2.Looper检查消息队列(MessageQueue先进先出)中是否有消息
3.如果检测到MessageQueue有消息就发送消息(1.obtainMessage2.msg.obj = “1”3.sendMessage)到HandlerMessage把消息传递回去Message msg = new Message();
Message msg = obtainMessage();//使用消息池,消息对象复用,不用每次都new(消息对象池的机制:链表结构)//handler机制:
1.Message 消息对象,内部使用链表数据结构实现一个消息池,用于复用,避免大量创建消息对象,造成内存浪费
2.Handler 消息处理者,通过该对象把消息存入消息队列,并通过handlerMessage方法处理消息
3.MessageQueue消息队列,用于存储Message对象的数据结构,先进先出
4.Looper消息队列的处理者,用于循环检测消息队列(MessageQueue),从消息队列中一个一个的取出消息对象,传入HandlerMessage方法中
11.Handler内存泄露分析
package com.recycler.zx.zxrecyclerview.Handler;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.recycler.zx.zxrecyclerview.R;
import java.lang.ref.WeakReference;
//Handler的内存泄露问题
//1.定义一个内部类时,会默认拥有外部类对象的引用,所以建议使用内部类时,最好定义一个静态(static)内部类(因为静态内部类就相当于一个外部类,不拥有外部类的引用)
//2.引用的强弱:强引用(new 出来的对象,就是强引用,就算内存不足也不会被自动回收,想要回收必须把对象置空或销毁当前对象,回收器才会回收)
// ->软引用(A引用B,当B内存不足的时候,系统就会回收它)
// ->弱引用(引用的对象如果不存在就得不到)
//3.
public class MemoryOverflowActivity extends AppCompatActivity {
private String name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memory_overflow);
//这样写会出现内存泄露
/*1.当Handler作为内部类使用的时候,那么handler持有外部类的引用;
如果外部类退出的时候,handler还在运行的话,外部类(Activity)就退出不了,就算退出了,还还在占用着内存。那么就造成了内存溢出(泄露)
(Handler依赖于外部类)*/
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
}
},60*10*1000);//延迟10分钟执行run方法
Toast.makeText(this,"来过",Toast.LENGTH_SHORT).show();
finish();
}
private MyHandler handler = new MyHandler(this);
//这个是标准的Handler写法,1.static内部类(相当于外部类,不依赖外部类)2.弱引用(防止内存泄露)3.通过mWeakReference.get()返回一个Activity
private static class MyHandler extends Handler{
//软引用Activity
WeakReference mWeakReference;
public MyHandler(MemoryOverflowActivity activity){
mWeakReference = new WeakReference(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//如果MemoryOverflowActivity被销毁了,那么mWeakReference.get()返回的就是null
//如果返回null你就不能 name 变量(因为name属于MemoryOverflowActivity的变量,MemoryOverflowActivity为null,它的变量自然就不能使用)
//使用弱引用,就可以避免内存泄露(溢出)
MemoryOverflowActivity activity = mWeakReference.get();
if(activity != null) {
}
}
}
}
SplashAcitivity的Style
".FirstActivity" android:theme="@android:style/Theme.DeviceDefault.Light.NoA
12.执行耗时操作的第二种方式(AsyncTask),第一种是Thread
package com.recycler.zx.zxrecyclerview.Handler;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.recycler.zx.zxrecyclerview.R;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import butterknife.Bind;
import butterknife.ButterKnife;
//Handler的内存泄露问题
//1.定义一个内部类时,会默认拥有外部类对象的引用,所以建议使用内部类时,最好定义一个静态(static)内部类(因为静态内部类就相当于一个外部类,不拥有外部类的引用)
//2.引用的强弱:强引用(new 出来的对象,就是强引用,就算内存不足也不会被自动回收,想要回收必须把对象置空或销毁当前对象,回收器才会回收)
// ->软引用(A引用B,当B内存不足的时候,系统就会回收它)
// ->弱引用(引用的对象如果不存在就得不到)
//3.
public class MemoryOverflowActivity extends AppCompatActivity {
@Bind(R.id.textView2)
TextView textView2;
@Bind(R.id.progressBar2)
ProgressBar progressBar2;
private String name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memory_overflow);
ButterKnife.bind(this);
//这样写会出现内存泄露
/*1.当Handler作为内部类使用的时候,那么handler持有外部类的引用;
如果外部类退出的时候,handler还在运行的话,外部类(Activity)就退出不了,就算退出了,还还在占用着内存。那么就造成了内存溢出(泄露)
(Handler依赖于外部类)*/
/*new Handler().postDelayed(new Runnable() {
@Override
public void run() {
}
}, 60 * 10 * 1000);//延迟10分钟执行run方法
Toast.makeText(this, "来过", Toast.LENGTH_SHORT).show();
finish();*/
}
private MyHandler handler = new MyHandler(this);
//这个是标准的Handler写法,1.static内部类(相当于外部类,不依赖外部类)2.软引用(防止内存泄露)3.通过mWeakReference.get()返回一个Activity
private static class MyHandler extends Handler {
//软引用Activity
WeakReference mWeakReference;
public MyHandler(MemoryOverflowActivity activity) {
mWeakReference = new WeakReference(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//如果MemoryOverflowActivity被销毁了,那么mWeakReference.get()返回的就是null
//如果返回null你就不能 name 变量(因为name属于MemoryOverflowActivity的变量,MemoryOverflowActivity为null,它的变量自然就不能使用)
//使用软引用,就可以避免内存泄露(溢出)
MemoryOverflowActivity activity = mWeakReference.get();
if (activity != null) {
}
}
}
//通过AsyncTask实现一个异步任务
private static class DownLoadAsynTask extends AsyncTask<String, Integer, String> {
private MemoryOverflowActivity mActivity;//这样写是有问题的,你既然使用了弱引用,就不能申明成员变量
在下面的每个方法中,只要你用到了你就必须通过mWeakReference.get();方法获取,不能直接申明一个成员变量接收
public DownLoadAsynTask(MemoryOverflowActivity activity) {
WeakReference mWeakReference = new WeakReference(activity);
mActivity = mWeakReference.get();
}
//执行任务之前触发,可以做一些初始化工作,主线程调用的
@Override
protected void onPreExecute() {
super.onPreExecute();
mActivity.textView2.setText("开始执行下载任务");
mActivity.progressBar2.setProgress(0);
}
//执行后台任务的方法,类似于线程,所以不能在该方法中访问Ui组件
@Override
protected String doInBackground(String... params) {
String imgurl = params[0];
try {
URL url = new URL(imgurl);
//打开连接
HttpURLConnection con = (HttpURLConnection) url.openConnection();
int size = con.getContentLength();
//0:表示需要更新最大进度值1:表示更新当前进度值
publishProgress(0,size);
InputStream in = con.getInputStream();
byte[] bytes = new byte[20];
int len = -1;
while((len = in.read(bytes)) != -1) {
//out.write(bytes,0,size);
publishProgress(1,len);//更新当前进度
//out.flush();
}
//out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
return "error";
}
return "success";
}
//更新进度值
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
switch (values[0]){
case 0:
mActivity.progressBar2.setMax(values[1]);
break;
case 1:
mActivity.progressBar2.incrementProgressBy(values[1]);
break;
}
}
//当doInBackground被调用返回的时候调用
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if(s.equals("success")) {
mActivity.textView2.setText("下载完成");
}else {
Toast.makeText(mActivity,"失败",Toast.LENGTH_SHORT).show();
}
}
}
public void download(View v) {
DownLoadAsynTask task = new DownLoadAsynTask(this);
task.execute("http://p2.so.qhimg.com/t01e767afd2dbff19ac.jpg");
}
}
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.recycler.zx.zxrecyclerview.Handler.MemoryOverflowActivity">
"wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/textView2"
android:onClick="download"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
"?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/progressBar2"
android:layout_below="@+id/textView2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
13.文件管理
package com.recycler.zx.zxrecyclerview.FileReadWriter;
import android.content.Context;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.recycler.zx.zxrecyclerview.R;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
public class FileActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file);
try {
//存储私有文件
savePrivateFile();
//读取私有文件
readPrivateFile();
//读取res/raw
readRawFile();
//读取缓存文件
readCacheFile();
//sd卡管理:写入
writeToSDcard();
} catch (Exception e) {
e.printStackTrace();
}
}
//判断有sd卡,并且不是只读的
private boolean isExternalStorageWritable(){
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)){//是否有sd卡
//判断是不是只读的sd卡
if(!state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
return true;
}
return false;
}
return false;
}
private void writeToSDcard() {
if(isExternalStorageWritable()) {
//访问sd卡路径
Environment.getExternalStorageDirectory().getPath();
//可以访问和保存不同类型的 storage/sdcard/movies丶storage/sdcard/pictures
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
}
}
//写入外部(sd卡)私有文件
private void writePrivateToSDcard() {
//别的程序无法访问
//getExternalFilesDir在手机把内部存储当做外部sd卡存储使用的时候此方法返回null
//storage/sdcard/android/data/com.recycler.zx.zxrecyclerview/1.txt
File file = getExternalFilesDir(null);
if(file != null) {
try {
FileOutputStream out = new FileOutputStream(file+"/1.txt");
PrintStream ps = new PrintStream(out);
ps.print("1111111111111");
ps.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//写入缓存到外部sd卡
private void writeCacheFileToSDcard() {
//别的程序无法访问
//getExternalFilesDir在手机把内部存储当做外部sd卡存储使用的时候此方法返回null
//storage/sdcard/android/data/com.recycler.zx.zxrecyclerview/1.txt
try {
File file = File.createTempFile("sss",null,getExternalCacheDir());
if(file != null) {
FileOutputStream out = new FileOutputStream(file+"/1.txt");
PrintStream ps = new PrintStream(out);
ps.print("1111111111111");
ps.close();
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void readCacheFile() {
try {
File file = File.createTempFile("temp.tmp",null,getCacheDir());
FileOutputStream out = new FileOutputStream(file);
PrintStream ps = new PrintStream(out);
ps.print("星星是");
} catch (IOException e) {
e.printStackTrace();
}
}
private void readRawFile() {
try{
InputStream is = getResources().openRawResource(R.raw.a);
StringBuffer sb2 = new StringBuffer();
byte[] bs2 = new byte[1024];
int len2 = -1;
while((len2 = is.read(bs2))!=-1) {
sb2.append(new String(bs2,0,bs2.length));
}
is.close();
Toast.makeText(this,sb2,Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void readPrivateFile() {
try{
InputStream in = openFileInput("a.txt");
StringBuffer sb = new StringBuffer();
byte[] bs = new byte[1024];
int len = -1;
while((len = in.read(bs))!=-1) {
sb.append(new String(bs,0,bs.length));
}
in.close();
Toast.makeText(this,sb,Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void savePrivateFile() {
try{
OutputStream out = openFileOutput("a.txt", Context.MODE_APPEND);//MODE_PRIVATE代表覆盖,MODE_APPEND代表追加
String info = "1111";
byte[] bytes = info.getBytes();
out.write(bytes,0,bytes.length);
} catch (Exception e) {
e.printStackTrace();
}
}
}
总结:
1.凡是遇到 {} 就用对象解析
public MyWeather parseJsonArrayFromGsons2(){
String weatherList = readAssertFile(“cache/Weather.json”);
Gson gson = new Gson();
return gson.fromJson(weatherList, MyWeather.class);
}
遇到:[] 就用数组解析
public List parseJsonArrayFromGsons(){
String citylist = readAssertFile(“cache/StoreTypeList.json”);
Type type = new TypeToken