您的位置:  首页 > 技术 > 前端 > 正文

安卓开发整理

2022-08-25 17:00 https://my.oschina.net/u/3768341/blog/5569275 算法之名 次阅读 条评论

先来一个HelloWorld.

XML布局文件

<?xml version="1.0" encoding="utf-8"?><!--线性布局--><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:gravity="center">    <TextView        android:id="@+id/tv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World" />    </LinearLayout>

事件响应代码为将英文修改成中文。

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);//        设置屏幕组件需要用的布局        setContentView(R.layout.activity_main);        TextView tv = findViewById(R.id.tv);//        修改文本控件的文字        tv.setText("你好,世界");    }

}

最后在手机上显示的画面如下

创建第二个页面

在res/layout文件夹下面新建一个xml文件

在res/values的strings.xml文件中添加内容

<resources>    <string name="app_name">OCR</string>    <string name="text2">Activity Main2</string></resources>

activity_main2.xml的布局内容如下

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:gravity="center">    <TextView        android:id="@+id/tv2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/text2" /></LinearLayout>

在清单文件AndroidManifest.xml文件中添加activity_main2的配置。

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.guanjian.ocr">    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/Theme.OCR">        <activity            android:name=".MainActivity"            android:exported="true"            android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity android:name=".MainActivity2" />    </application></manifest>

在Activity1中添加一个按钮来跳转到Activity2。

<?xml version="1.0" encoding="utf-8"?><!--线性布局--><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:gravity="center">    <TextView        android:id="@+id/tv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World" />    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="跳转" /></LinearLayout>

修改MainActivity的Java代码

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);//        设置屏幕组件需要用的布局        setContentView(R.layout.activity_main);        TextView tv = findViewById(R.id.tv);//        修改文本控件的文字        tv.setText("你好,世界");        Button button = findViewById(R.id.button);//        给button设定点击事件的侦听        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {//                创建一个意图对象                Intent intent = new Intent();                intent.setClass(MainActivity.this,MainActivity2.class);//                实现跳转                startActivity(intent);            }
        });    }

}

在Java主目录中创建MainActivity2的响应类。

public class MainActivity2 extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);    }
}

在手机上的运行效果如下

Activity生命周期

上图的说明可以见以下代码

public class MainActivity extends AppCompatActivity {    private static final String TAG = "ning";    /**     * 在页面载入的时候最先触发     * @param savedInstanceState     */    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.d(TAG,"Activity onCreate");//        设置屏幕组件需要用的布局        setContentView(R.layout.activity_main);        TextView tv = findViewById(R.id.tv);//        修改文本控件的文字        tv.setText("你好,世界");        Button button = findViewById(R.id.button);//        给button设定点击事件的侦听        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {//                创建一个意图对象                Intent intent = new Intent();                intent.setClass(MainActivity.this,MainActivity2.class);//                实现跳转                startActivity(intent);            }
        });    }    /**     * 在页面载入的时候第二个触发     */    @Override    protected void onStart() {        super.onStart();        Log.d(TAG,"Activity onStart");    }    /**     * 在页面载入的时候第三个触发,结束时页面可见     */    @Override    protected void onResume() {        super.onResume();        Log.d(TAG,"Activity onResume");    }    /**     * 在页面跳转离开的时候触发     */    @Override    protected void onPause() {        super.onPause();        Log.d(TAG,"Activity onPause");    }    /**     * 在页面完全消失的时候触发     */    @Override    protected void onStop() {        super.onStop();        Log.d(TAG,"Activity onStop");    }    /**     * 从其他页面返回该页面时首次执行     * 然后执行onStart和onResume     */    @Override    protected void onRestart() {        super.onRestart();        Log.d(TAG,"Activity onRestart");    }    /**     * 从主界面返回安卓桌面的时候触发     */    @Override    protected void onDestroy() {        super.onDestroy();        Log.d(TAG,"Activity onDestroy");    }
}

当我们打开安卓app的时候会显示日志

D/ning: Activity onCreate
D/ning: Activity onStart
D/ning: Activity onResume

当我们点击跳转按钮会显示日志

D/ning: Activity onPause
D/ning: Activity onStop

当我们从跳转页面返回主界面时会显示日志

D/ning: Activity onRestart
D/ning: Activity onStart
D/ning: Activity onResume

当我们从主界面返回安卓桌面时会显示日志

D/ning: Activity onPause
D/ning: Activity onStop
D/ning: Activity onDestroy

当我们点击了跳转按钮立刻返回主界面时会显示日志

D/ning: Activity onPause
D/ning: Activity onResume

这里有一个值得说明的地方,当App隐藏于后台的时候,我们启动了非常占用内存的App,比如游戏,此时安卓系统会将该进程杀死释放内存给游戏使用。当我们再次进入该App的时候会显示D/ning: Activity onCreate而不是D/ning: Activity onRestart。这几个触发动作的具体应用如下

  1. onCreate:创建活动,把页面布局加载进内存,进入初始状态。
  2. onStart:开始活动,把活动页面显示在屏幕上,进入了就绪状态。
  3. onResume:恢复活动,活动页面进入活跃状态,能够与用户正常交互,例如允许响应用户的点击动作;允许用户输入文字等等。
  4. onPause:暂停活动,页面进入暂停状态,无法与用户进行正常交互。
  5. onStop:停止活动,页面将不在屏幕上显示。
  6. onDestroy:销毁活动,回收活动占用的系统资源,把页面从内存中清除。
  7. onRestart:重启活动,重新加载内存中的页面数据。
  8. onNewIntent:重用已有的活动实例。

Intent

Intent是各个组件之间信息沟通的桥梁,它用于Android各组件之间的通信,主要完成下列工作:

  1. 标明本次通信请求从哪里来,到哪里去,要怎么走。
  2. 发起方携带本次通信需要的数据内容,接收方从收到的意图中解析数据。
  3. 发起方若想判断接收方的处理结果,意图就要负责接收方传回应答的数据内容。
  • 显式Intent:直接指定来源活动与目标活动,属于精确匹配。它有3种构建方式
  1. 在Intent的构造函数中指定。
  2. 调用意图对象的setClass方法指定。
  3. 调用意图对象的setComponent方法指定。
            @Override            public void onClick(View view) {//                创建一个意图对象,第一种方式//                Intent intent = new Intent(MainActivity.this,MainActivity2.class);//                第二种方式                Intent intent = new Intent();                intent.setClass(MainActivity.this,MainActivity2.class);//                第三种方式//                Intent intent = new Intent();//                它可以调用第三方的控件,使用包名(字符串)和类名(字符串)来调用//                ComponentName component = new ComponentName(MainActivity.this,MainActivity2.class);//                intent.setComponent(component);//                实现跳转                startActivity(intent);            }

  • 隐式Intent:没有明确指定要跳转的目标活动,只给出一个动作字符串让系统自动匹配,属于模糊匹配。

现在我们在Activity2的页面中添加如下的布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:gravity="center">    <TextView        android:id="@+id/tv2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/text2" />    <TextView        android:id="@+id/tv3"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:padding="5dp"        android:text="点击以下按钮将向号码12345发起请求" />    <Button        android:id="@+id/btn_dial"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="跳到拨号页面" /></LinearLayout>

在Activity2的Java代码中添加

public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        findViewById(R.id.btn_dial).setOnClickListener(this);    }    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.btn_dial:
                Intent intent = new Intent();//                隐式跳转到拨号界面                intent.setAction(Intent.ACTION_DIAL);                Uri uri = Uri.parse("tel:12345");                intent.setData(uri);                startActivity(intent);                break;            default:                break;        }
    }
}

运行结果

  • 向下一个Activity传递数据

我们在Activity的主界面的布局文件中添加如下代码

<?xml version="1.0" encoding="utf-8"?><!--线性布局--><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:gravity="center">    <TextView        android:id="@+id/tv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World" />    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="跳转" />    <TextView        android:id="@+id/tv_send"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="今天天气很晴朗" />    <Button        android:id="@+id/button_send"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="发送信息" /></LinearLayout>

在Activity的Java代码中添加

public class MainActivity extends AppCompatActivity {    private static final String TAG = "ning";    private TextView tvSend;    /**     * 在页面载入的时候最先触发     * @param savedInstanceState     */    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.d(TAG,"Activity onCreate");//        设置屏幕组件需要用的布局        setContentView(R.layout.activity_main);        TextView tv = findViewById(R.id.tv);//        修改文本控件的文字        tv.setText("你好,世界");        Button button = findViewById(R.id.button);//        给button设定点击事件的侦听        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {//                创建一个意图对象,第一种方式//                Intent intent = new Intent(MainActivity.this,MainActivity2.class);//                第二种方式                Intent intent = new Intent();                intent.setClass(MainActivity.this,MainActivity2.class);//                第三种方式//                Intent intent = new Intent();//                它可以调用第三方的控件,使用包名(字符串)和类名(字符串)来调用//                ComponentName component = new ComponentName(MainActivity.this,MainActivity2.class);//                intent.setComponent(component);//                实现跳转                startActivity(intent);            }
        });        tvSend = findViewById(R.id.tv_send);        findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this,MainActivity2.class);//                创建一个包裹对象                Bundle bundle = new Bundle();                bundle.putString("request_time", new Date().toString());                bundle.putString("request_context",tvSend.getText().toString());                intent.putExtras(bundle);                startActivity(intent);            }
        });    }    /**     * 在页面载入的时候第二个触发     */    @Override    protected void onStart() {        super.onStart();        Log.d(TAG,"Activity onStart");    }    /**     * 在页面载入的时候第三个触发,结束时页面可见     */    @Override    protected void onResume() {        super.onResume();        Log.d(TAG,"Activity onResume");    }    /**     * 在页面跳转离开的时候触发     */    @Override    protected void onPause() {        super.onPause();        Log.d(TAG,"Activity onPause");    }    /**     * 在页面完全消失的时候触发     */    @Override    protected void onStop() {        super.onStop();        Log.d(TAG,"Activity onStop");    }    /**     * 从其他页面返回该页面时首次执行     * 然后执行onStart和onResume     */    @Override    protected void onRestart() {        super.onRestart();        Log.d(TAG,"Activity onRestart");    }    /**     * 从主界面返回安卓桌面的时候触发     */    @Override    protected void onDestroy() {        super.onDestroy();        Log.d(TAG,"Activity onDestroy");    }
}

在Activity2中获取意图中的数据放入tv2中。

public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {    private TextView tv2;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        findViewById(R.id.btn_dial).setOnClickListener(this);        tv2 = findViewById(R.id.tv2);//        从上一个页面的意图中获取包裹        Bundle bundle = getIntent().getExtras();        String requestTime = bundle.getString("request_time");        String requestContext = bundle.getString("request_context");        String desc = String.format("收到请求消息:\n请求时间:%s\n请求内容:%s",                requestTime,requestContext);        tv2.setText(desc);    }    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.btn_dial:
                Intent intent = new Intent();//                隐式跳转到拨号界面                intent.setAction(Intent.ACTION_DIAL);                Uri uri = Uri.parse("tel:12345");                intent.setData(uri);                startActivity(intent);                break;            default:                break;        }
    }
}

运行结果

  • 向上一个Activity返回数据

现在我们要回一个信息给到主界面,说今天天气很热。

在Activity2中增加一个按钮,布局文件如下

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:gravity="center">    <TextView        android:id="@+id/tv2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/text2" />    <TextView        android:id="@+id/tv_response"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="待返回的消息为:今天天气很热" />    <Button        android:id="@+id/btn_response"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="发送返回信息" />    <TextView        android:id="@+id/tv3"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:padding="5dp"        android:text="点击以下按钮将向号码12345发起请求" />    <Button        android:id="@+id/btn_dial"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="跳到拨号页面" /></LinearLayout>

现在我们在Activity的主界面的Java代码中就不仅仅是普通的跳转到Activity2了,而是需要注册一个可以等待返回的ActivityResult。跳转的方式也不再是startActivity(intent);注意,以下代码都改成了Lambda表达式的形式,关于lambda表达式的内容可以参考Java函数式编程整理

public class MainActivity extends AppCompatActivity {    private static final String TAG = "ning";    private TextView tvSend;    private ActivityResultLauncher<Intent> register;    /**     * 在页面载入的时候最先触发     * @param savedInstanceState     */    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.d(TAG,"Activity onCreate");//        设置屏幕组件需要用的布局        setContentView(R.layout.activity_main);        TextView tv = findViewById(R.id.tv);//        修改文本控件的文字        tv.setText("你好,世界");        Button button = findViewById(R.id.button);//        给button设定点击事件的侦听        button.setOnClickListener(view ->  {//            创建一个意图对象,第一种方式//            Intent intent = new Intent(MainActivity.this,MainActivity2.class);//            第二种方式            Intent intent = new Intent();            intent.setClass(MainActivity.this,MainActivity2.class);//            第三种方式//            Intent intent = new Intent();//            它可以调用第三方的控件,使用包名(字符串)和类名(字符串)来调用//            ComponentName component = new ComponentName(MainActivity.this,MainActivity2.class);//            intent.setComponent(component);//            实现跳转            startActivity(intent);        });        tvSend = findViewById(R.id.tv_send);//        注册ActivityResult,并通过回调函数获取返回的信息        register = registerForActivityResult(new StartActivityForResult(), result ->  {            if (result != null) {
                Intent intent = result.getData();                if (intent != null && result.getResultCode() == Activity.RESULT_OK) {
                    Bundle bundle = intent.getExtras();                    String responseTime = bundle.getString("response_time");                    String responseContext = bundle.getString("response_context");                    String desc = String.format("收到返回消息:\n返回时间:%s\n返回内容:%s",                            responseTime,responseContext);                    tv.setText(desc);                }
            }
        });        findViewById(R.id.button_send).setOnClickListener(view ->  {
            Intent intent = new Intent(MainActivity.this,MainActivity2.class);//                创建一个包裹对象            Bundle bundle = new Bundle();            bundle.putString("request_time", new Date().toString());            bundle.putString("request_context",tvSend.getText().toString());            intent.putExtras(bundle);            register.launch(intent);        });    }    /**     * 在页面载入的时候第二个触发     */    @Override    protected void onStart() {        super.onStart();        Log.d(TAG,"Activity onStart");    }    /**     * 在页面载入的时候第三个触发,结束时页面可见     */    @Override    protected void onResume() {        super.onResume();        Log.d(TAG,"Activity onResume");    }    /**     * 在页面跳转离开的时候触发     */    @Override    protected void onPause() {        super.onPause();        Log.d(TAG,"Activity onPause");    }    /**     * 在页面完全消失的时候触发     */    @Override    protected void onStop() {        super.onStop();        Log.d(TAG,"Activity onStop");    }    /**     * 从其他页面返回该页面时首次执行     * 然后执行onStart和onResume     */    @Override    protected void onRestart() {        super.onRestart();        Log.d(TAG,"Activity onRestart");    }    /**     * 从主界面返回安卓桌面的时候触发     */    @Override    protected void onDestroy() {        super.onDestroy();        Log.d(TAG,"Activity onDestroy");    }
}

Activity2中的返回信息的代码如下

public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {    private TextView tv2;    private final String msg = "今天天气很热";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        findViewById(R.id.btn_dial).setOnClickListener(this);        tv2 = findViewById(R.id.tv2);//        从上一个页面的意图中获取包裹        Bundle bundle = getIntent().getExtras();        String requestTime = bundle.getString("request_time");        String requestContext = bundle.getString("request_context");        String desc = String.format("收到请求消息:\n请求时间:%s\n请求内容:%s",                requestTime,requestContext);        tv2.setText(desc);        findViewById(R.id.btn_response).setOnClickListener(this);    }    @Override    public void onClick(View view) {
        Intent intent = new Intent();        switch (view.getId()) {            case R.id.btn_dial://                隐式跳转到拨号界面                intent.setAction(Intent.ACTION_DIAL);                Uri uri = Uri.parse("tel:12345");                intent.setData(uri);                startActivity(intent);                break;            case R.id.btn_response:
                Bundle bundle = new Bundle();                bundle.putString("response_time",new Date().toString());                bundle.putString("response_context",msg);                intent.putExtras(bundle);                setResult(Activity.RESULT_OK,intent);//                页面返回跳转                finish();                break;            default:                break;        }
    }
}

运行结果

运行时动态申请权限

展开阅读全文                                    
  • 0
    感动
  • 0
    路过
  • 0
    高兴
  • 0
    难过
  • 0
    搞笑
  • 0
    无聊
  • 0
    愤怒
  • 0
    同情
热度排行
友情链接