1.调试
Log.v // 冗余信息
Log.i // 普通信息
Log.d // 调试信息
Log.w // 警告信息
Log.e // 错误信息
AndroidStudio 查看源码及文件:敲击滚轮
2.布局和控件
1.去掉应用标题(string文件)
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
2.强制横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //强制横屏
3.隐去电量显示栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉电量信息和时间栏
4.布局建议:用线性布局和约束布局即可LineLayout/ConstrainLayout
5.关于match_parent,wrap_content
match_parent表示让当前控件的大小和父布局的大小一样,也就是由父布局来决定当前控件的大小
wrap_content表示让当前的控件大小能够刚好包含里面的内容,也就是由控件内容决定当前控件的大小
3.简单控件使用方法
button
checkbox
radioGroup(radiobutton的组合)
ImageView
package szly.example.simpletest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private Button button1;
private ImageView imageView;
private ImageView imageView2;
private CheckBox checkBox;
private RadioGroup radioGroup;
private EditText editText;
private EditText editText2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉电量信息和时间栏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //强制横屏
button1 = findViewById(R.id.button);
textView = findViewById(R.id.textView2);
imageView = findViewById(R.id.imageView);
imageView2 = findViewById(R.id.imageView2);
checkBox = findViewById(R.id.checkBox);
radioGroup = findViewById(R.id.radioGroup);
editText = findViewById(R.id.editText3);
editText2 = findViewById(R.id.editText6);
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v)
{
textView.setText("HelloWorld");
}
});
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if(checkedId == R.id.redButton)
{
editText.setText("RED");
imageView.setColorFilter(0xFF0000);
}
else{
editText.setText("YELLOW");
imageView.setColorFilter(0x00FF00);
}
}
});
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked)
{
imageView2.setVisibility(View.VISIBLE);
}
else {
imageView2.setVisibility(View.INVISIBLE);
}
}
});
}
}
4.用toast短暂提示信息
Toast.LENGTH_LONG 3.5秒,Toast.LENGTH_SHORT 2秒。
Toast t = Toast.makeText(getApplicationContext(),"Hello World", Toast.LENGTH_LONG);
t.show();
5.Activity
为活动绑定布局
setContentView(R.layout.activity_main);
启动活动
startActivity(intent);
结束活动
finish();
生命周期
启动 onCreate(); onStart();
运行(交互中)
暂停(用户操作无反应,界面仍然显示) onPause();
停止(不可见)() onStop();
销毁(清出内存) onDestroy();
数据传递
方法1:(推荐)
putExtra(name,value);要将数据封装到Intent对象中。
Activity1
Intent intent = new Intent(MainActivity1.this,Main2Activity.class);//指明数据传递方向
intent.putExtra("name","guangjie");
intent.putExtra("score",130);
startActivity(intent);
Activity2
Intent intent = getIntent();
String name = intent.getStringExtra("name");
int score = intent.getIntExtra("score",0);
方法2:Bundle
Activity1
Intent intent = new Intent(MainActivity1.this,Main2Activity.class);//指明数据传递方向
Bundle bundle = new Bundle();
bundle.putString("name","guangjie");
bundle.putInt("score",130);
intent.putExtras(bundle);
startActivity(intent);
Activity2
Bundle bundle = getIntent().getExtras();
String name = bundle.getString("name");
int score = bundle.getInt("score",0);
关于Activity的基本操作,生命周期,数据传递的举例
## Activity1
package szly.example.activitybase;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast t = Toast.makeText(getApplicationContext(),"Hello World",Toast.LENGTH_LONG);
t.show();
button1 = findViewById(R.id.button);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
intent.putExtra("name","guangjie2333");
startActivityForResult(intent,1);
//startActivity(intent);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1)
{
if (requestCode == 1)
{
String recieve = data.getStringExtra("Result");
Toast t2 = Toast.makeText(getApplicationContext(),recieve,Toast.LENGTH_LONG);
t2.show();
}
}
}
@Override
protected void onStart()
{
super.onStart();
Log.d("Lifecycle","MainActivity:onStart被调用:");
}
@Override
protected void onResume() {
super.onResume();
Log.d("Lifecycle","MainActivity:onResume被调用");
}
@Override
protected void onPause() {
super.onPause();
Log.d("Lifecycle","MainActivity:onPause被调用");
}
@Override
protected void onStop() {
super.onStop();
Log.d("Lifecycle","MainActivity:onStop被调用");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("Lifecycle","MainActivity:onDestroy被调用");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("Lifecycle","MainActivity:onRestart被调用");
}
}
## Activity2
package szly.example.activitybase;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.Timer;
import java.util.TimerTask;
public class Main2Activity extends AppCompatActivity {
private Button button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent = getIntent();
String name = intent.getStringExtra("name");
final Toast t = Toast.makeText(getApplicationContext(),name + "正在学习Android",Toast.LENGTH_LONG);
TimerTask task = new TimerTask(){
@Override
public void run()
{
t.show();
}
};
Timer timer = new Timer();
timer.schedule(task,2000);//延时两秒执行
button2 = findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intentForResult = new Intent();
intentForResult.putExtra("Result","收到,guangjie2333正在学习Android");
setResult(1,intentForResult);
finish();
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.e("Lifecycle","Main2Activity:onStart被调用");
}
@Override
protected void onResume() {
super.onResume();
Log.e("Lifecycle","Main2Activity:onResume被调用");
}
@Override
protected void onPause() {
super.onPause();
Log.e("Lifecycle","Main2Activity:onPause被调用");
}
@Override
protected void onStop() {
super.onStop();
Log.e("Lifecycle","Main2Activity:onStop被调用");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e("Lifecycle","Main2Activity:onDestroy被调用");
}
@Override
protected void onRestart() {
super.onRestart();
Log.e("Lifecycle","Main2Activity:onRestart被调用");
}
}
Android 线程
当一个应用第一次启动时,Android会同时启动一个对应的主线程(Main
Thread),主线程主要负责处理与UI相关的事件(用户的按钮点击事件,用
户手势事件以及屏幕绘图事件等),并把相关的事件分发到对应的组件进行
处理,所以主线程通常又被叫做UI线程。
在开发Android 应用时必须遵守单线程模型的原则:
不要阻塞UI线程
确保只在UI线程中访问Android UI工具包
如果在非UI线程中直接操作UI控件,会抛出
android.view.ViewRoot$CalledFromWrongThreadException的异常,这
与普通的java程序不同
Handler 消息机制
Message:消息,理解为线程间交流的信息,包含消息ID、消息处理对象
和处理的数据等,统一放到Message Queue,最终由Handler处理。
Handler:非UI线程与UI线程通信的接口,消息处理者,专门负责
Message的发送和处理:
obtainMessage():获取消息
sendMessage(Message msg):发送消息
handleMessage(Message msg):处理消息
Message Queue:Message Queue消息队列,用来存放通过Handler
发布的消息,按照先进先出执行。每个message queue都会有一个对应
的Handler。Handler会向message queue通过两种方法发送消息:
sendMessage或post。这两种消息都会插在message queue队尾并按
先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过
sendMessage发送的是一个message对象,会被Handler的
handleMessage()函数处理;而通过post方法发送的是一个runnable对
象,则会自己执行。
Looper:Looper是每条线程里的Message Queue的管家。Android没
有全局的Message Queue,而Android会自动替主线程(UI线程)建立
Message Queue,但在子线程里并没有建立Message Queue。
写一个简单的多线程 程序
package szly.example.threadmessage;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button button;
private TextView textView;
private ProgressBar progressBar;
private int process = 0;
//添加线程消息处理
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
textView.setText(msg.arg1 + "%");
progressBar.setProgress(msg.arg1);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
textView = findViewById(R.id.textView);
progressBar = findViewById(R.id.progressBar);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"测试中",Toast.LENGTH_LONG).show();
}
});
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true)
{
process++;
//msg 是主线程handler获取的消息
Message msg = handler.obtainMessage();
msg.arg1 = process;
handler.sendMessage(msg);
if (process >= 100)
{
process = 0;
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
}
}
因为包名和项目名相同产生的error
ERROR Type3
app闪退的原因总结
1.线性布局的Text文本中 没有规定 android:orientation
2.在使用ListView控件时 listview.setAdapter出现问题
解决办法:对于 ArraylistAdapter关联的xml文件 要非常注意 ,记得删除所有的布局样式。