《第一行代码》第二章
《第一行代码》第二章总结
上一章总结是在看完后写的,感觉遗漏很多,从这章起是边阅读边总结。
目录由于有了新的事情,《第一行代码》的总结要停一段时间,但不会太久。
- 《第一行代码》第二章总结
- 手动创建活动
- 在活动中使用Toast():
- 在活动中使用Menu:
- 销毁一个活动:
- Intent篇
- 使用显式Intent
- 使用隐式Intent
- 更多隐式Intent
- 接上
- 向下一个活动传递数据
- 返回数据给上一个活动
- 通过back返回
- 活动周期篇
- 体验活动的生命周期
- 活动的启动模式
- standard
- singelTop
- singelTask
- singleInstance*
- 了解当前活动的技巧
- 出现的问题
手动创建活动
- 选择 Add No Activity ,创建一个活动。
- 在res 下创建 layout 文件夹,在文件夹下创建 first_layout 布局。
- 在布局中添加一个按钮。
- 在活动中加载布局。
- 在AndroidManifest 文件中注册。
- 在AndroidManifest 中配置主活动,在内部加入
。
在活动中使用Toast():
-
在 onCreat()中添加。
Button button1 = (Button) findViewById(R.id.button_1); button1.setOnClickListener(new View.OnClickListener(){ //注册监听器 public void onClick(View v){ Toast.makeText(MainActivity.this, "You clicked Button 1", Toast.LENGTH_SHORT).show(); } });
-
通过findViewById()方法获得布局元素,返回的是View对象,(Button)转型成Button对象。
-
为按钮注册监听器。
- makeText ( Context对象, 文本内容, 时长).show()。 时长有:Toast.LENGTH_SHORT 与 Toast.LENGTH_LONG
Ps:在这里设置了自动导包
@+id/xxx 在 xml 定义一个id
@id/xxx 在 xml 引入一个id
在活动中使用Menu:
-
res下创建menu文件夹,创建main,创建
- 标签创建菜单项。
-
在活动中添加onCreatetionsMenu(),使用getMenuInflater().inflate(R.menu.main,menu),第一个参数为创建菜单的资源文件,第二个参数为菜单项添加到的Menu对象。
public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main,menu); return true; }
-
定义菜单响应事件,在活动中重写onOptionsItemSelected(),通过调用item.getItemId() 来判断我们点击的是哪一个菜单项。
public boolean onOptionsItemSelected(MenuItem item){ switch (item.getItemId()){ case R.id.app_item: Toast.makeText(this,"You clicked Add",Toast.LENGTH_SHORT).show(); break; case R.id.remove_item: Toast.makeText(this,"You clicked Remove",Toast.LENGTH_SHORT).show(); break; default: } return true; }
销毁一个活动:
-
修改按钮监听器中的代码(我把之前的代码注释掉了):
button1.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ //Toast.makeText(MainActivity.this, "You clicked Button 1", Toast.LENGTH_SHORT).show(); finish(); } });
Intent篇
使用显式Intent
Ps:Intent是Android程序中各组件之间进行交互的一种重要方式。
-
创建第二个活动
-
修改第一个活动中按钮的点击事件(同样注释):
button1.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ //Toast.makeText(MainActivity.this, "You clicked Button 1", Toast.LENGTH_SHORT).show(); //finish(); Intent intent = new Intent(MainActivity.this,SecondActivity.class); startActivity(intent); } });
-
先构建Intent ,传入MainActivity.this 作为上下文,传入 SecondActivity.class 作为目标活动。
-
通过startActivity()方法执行Intent。
-
按下back键销毁当前活动,回到上一个活动。
使用隐式Intent
-
在 标签下配置
的内容 -
修改MainActivity中按钮的点击事件
button1.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ //Toast.makeText(MainActivity.this, "You clicked Button 1", Toast.LENGTH_SHORT).show(); //finish(); //Intent intent = new Intent(MainActivity.this,SecondActivity.class); //startActivity(intent); Intent intent = new Intent("com.example.androidtest.ACTION_START"); startActivity(intent); } });
-
标签声明当前活动可以响应 com.example.androidtest.ACTION_START 这个活动,
标签包含了一些附加信息,更精确指明当前活动能够响应的Intent中还可能带有的category。只有与 同时匹配上Intent 中指定的action 和 category 时,这个活动才能响应该 Intent。 -
android.intent.category.DEFAULT 是一种默认的 category ,在调用 startActivity 方法时会自动将这个category 添加到 Intent 中。
更多隐式Intent
-
修改主活动为
button1.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ Intent intent = new Intent(Intent.ACTION_VIEW); //指定Intent的action为Intent.ACTION_VIEW,为安卓内置动作 intent.setData(Uri.parse("http://www.baidu.com")); startActivity(intent); //通过Uri.parse()方法,将网址字符串解析成Uri对象,再调用setData()方法传递这个Uri对象。
-
setData()接受一个Uri对象,用于指定当前Intent正在操作的数据。
接上
-
创建活动 ThirdActivity 与 third_layout
-
在 AndroidManifest.xml中注册
-
进行配置
-
tools:ignore="AppLinkUrlError" 通过提示增加!
向下一个活动传递数据
-
修改主活动:
public void onClick(View v){ String data = "Hello SecondActivity"; Intent intent = new Intent(MainActivity.this,SecondActivity.class); intent.putExtra("extra_data",data); //接受两个参数,第一个是键 startActivity(intent); }
-
修改 SecondActivity :
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second_layout); Intent intent = getIntent(); //获取用于启动SecondActivity的Intent String data = intent.getStringExtra("extra_data"); Log.d("SecondActivity",data); }
返回数据给上一个活动
-
主活动中写入:
public void onClick(View v){ Intent intent = new Intent(MainActivity.this,SecondActivity.class); startActivityForResult(intent,1); //在活动销毁的时候返回一个结果给上一个活动。第二个参数是请求码,用于在之后的回调中判断数据的来源。 }
-
SecondActivity:
button2.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){Intent intent = new Intent(); intent.putExtra("data_return","Hello 主活动"); setResult(RESULT_OK, intent); //重要!专门用于上一个活动返回数据。第一个参数用于向上一个活动返回处理结果,一般只用RESULT_OK 或 RESULT_CANCELED这两个值,第二个参数则吧带有数据的Intent 传递回去。 finish();} //销毁活动 });
- 主活动重写 onActivityResult(): 回调的方法
protected void onActivityResult(int requestCode,int resultCode, Intent data) { //第一个参数是活动传入的请求码1,第二个参数是在返回数据时传入的处理结果RESULT_OK。 super.onActivityResult(requestCode, resultCode, data); //注意 switch (requestCode) { case 1: if (requestCode == RESULT_OK) { String returnedData = data.getStringExtra("data_return"); Log.d("MainActivity", returnedData); } break; default: } }
通过back返回
-
在以上的基础上,在SecondActivity 中重写:
public void onBackPressedf(){ Intent intent = new Intent(); intent.putExtra("data_return","Hello 主活动"); setResult(RESULT_OK,intent); finish(); }
活动周期篇
- 每个活动在其生命周期中最多可能会有4种状态。
- 运行状体
- 暂停状态
- 停止状态
- 销毁状态
体验活动的生命周期
-
新建项目,创建主活动、两个子活动(NormalActivity、DialogActivity)与对应的布局。两个子活动布局各添加一个TextView,主活动布局添加两个button。
-
修改AndroidManifest.xml:
-
修改主活动代码:
展开查看
private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button startNormalActivity = (Button) findViewById(R.id.start_normal_activity); Button startDialogActivity = (Button) findViewById(R.id.start_dialog_activity); startNormalActivity.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ Intent intent = new Intent(MainActivity.this,NormalActivity.class); startActivity(intent); } }); startDialogActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this,DialogActivity.class); } }); } @Override protected void onStart() { super.onStart(); Log.d(TAG,"onStart"); } @Override protected void onResume() { super.onResume(); Log.d(TAG,"onResume"); } @Override protected void onPause() { super.onPause(); Log.d(TAG,"onPause"); } @Override protected void onStop() { super.onStop(); Log.d(TAG,"onStop"); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG,"onDestory"); } @Override protected void onRestart() { super.onRestart(); Log.d(TAG,"onRestart"); }
活动的启动模式
standard
- standard是活动默认的启动模式。
- 使用standard模式的活动,每次启动都会创建该活动的一个新的实例。
singelTop
-
启动活动时若发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不再创建新的活动实例。
-
修改AndroidManifest.xml:
在activity标签内加
android:launchMode="singleTop"
singelTask
- 每次启动活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果发现没有就会创建一个新的活动实例。
singleInstance*
- 指定为singleInstance 模式的活动会启用一个新的返回栈来管理这个活动
了解当前活动的技巧
-
新建一个类(Java Class):无需注册
public class BaseActivity extends AppCompatActivity { //继承AppCompatActivity! @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("BaseActivity",getClass().getSimpleName()); } }
-
让所有类继承
BaseActivity
出现的问题
- 每次运行出现这样的错误信息:…… E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008cdf
…… E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008824 - 按照示例在隐式Intent活动中添加intent.addCategory(……)没有按照书里说的报错但程序运行终止了。
- 在<体验活动生命周期>处的试验中,点击第二个对话的按钮没反应,程序也没报错,网上两个方法都没用。