1、Activity
活动是用户可以看到并与之互动的单一屏幕。每个活动都会为用户提供一个界面以用于用户与应用交互。比如,一个邮件应用可能有一个显示邮件列表的活动,和另一个用于编写新邮件的活动。
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置内容视图
setContentView(R.layout.activity_main);
// 获取布局文件中的TextView组件
TextView textView = findViewById(R.id.text_view);
// 设置TextView的文本
textView.setText("Hello, Android!");
}
}
2、Service
服务是一个在后台运行的组件,它被用来执行长时间运行的操作或者为其他应用提供功能,而不提供用户界面。例如,一个服务可能在后台播放音乐,即使用户切换到其他应用也不会停止。
下面是一个后台播放音乐的服务示例,这是Android开发中一个常见的使用服务的场景,因为服务可以在不阻碍用户与应用其他部分交互的情况下,在后台执行长时间运行的操作。
首先,需要创建一个继承自Service
的类。在这个类中,你可以重写onStartCommand()
方法来处理服务的启动请求,并在这里开始播放音乐。同时,也应该重写onBind()
方法,尽管在这个例子中我们不会用到绑定服务的方式。
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class MusicService extends Service {
private MediaPlayer mediaPlayer;
@Override
public void onCreate() {
super.onCreate();
// 初始化MediaPlayer,这里直接使用了一个本地资源文件作为音乐示例
mediaPlayer = MediaPlayer.create(this, R.raw.example_song);
mediaPlayer.setLooping(true); // 设置循环播放
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start(); // 开始播放
}
return START_STICKY; // 当系统在服务运行时被杀死,之后又会重新创建服务
}
@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop(); // 停止播放
mediaPlayer.release(); // 释放资源
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
// 对于本示例,我们不提供绑定服务的方式
return null;
}
}
接着,需要在AndroidManifest.xml
文件中声明这个服务,这样系统就能识别并管理它了。下面代码<application ...>中的...表示省略,请勿复制粘贴 。
<application ...>
...
<service android:name=".MusicService" />
...
</application>
最后,可以从一个活动中启动和停止这个服务。以下是启动和停止服务的代码示例:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 当用户想要开始播放音乐时调用
public void startMusic(View view) {
Intent intent = new Intent(this, MusicService.class);
startService(intent); // 启动服务,开始播放音乐
}
// 当用户想要停止播放音乐时调用
public void stopMusic(View view) {
Intent intent = new Intent(this, MusicService.class);
stopService(intent); // 停止服务,音乐停止
}
}
3、Broadcast Receiver
广播接收器用于监听和响应应用或系统发送的广播消息。
例如,应用可以启动一个广播来通知其他应用数据已经发生变化。 再比如监听网络状态变化的情况。当设备的网络连接发生变化时(例如从无网络到有网络,或者从Wi-Fi切换到移动数据),系统会发送一个广播。应用可以通过注册相应的
BroadcastReceiver
来监听这些网络变化的广播,从而根据网络状态做出相应的处理,比如暂停或恢复数据同步。代码如下:
首先,创建一个BroadcastReceiver
子类来监听网络状态变化的广播:
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 NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 检查网络状态
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
// 判断是否连接到了有效网络
if (networkInfo != null && networkInfo.isConnected()) {
//Toast用于以弹窗的形式在手机应用界面显示相关消息
Toast.makeText(context, "Network available", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Network unavailable", Toast.LENGTH_SHORT).show();
}
}
}
接下来,在AndroidManifest.xml
文件中声明这个BroadcastReceiver
,并添加检查网络状态所需的权限:下面代码<application ...>中的...表示省略,请勿复制粘贴
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application ...>
<receiver android:name=".NetworkChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
注意:从Android 7.0(API 级别 24)开始,对于
CONNECTIVITY_CHANGE
这类隐式广播,系统不再在AndroidManifest.xml
中静态注册的BroadcastReceiver
中发送。不过,你仍然可以通过在代码中动态注册BroadcastReceiver
来接收这些广播:
public class MyActivity extends AppCompatActivity {
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onStart() {
super.onStart();
// 动态注册BroadcastReceiver
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, filter);
}
@Override
protected void onStop() {
super.onStop();
// 注销BroadcastReceiver
unregisterReceiver(networkChangeReceiver);
}
}
4、Content Provider
内容提供器管理应用的数据共享。通过内容提供器,其他应用可以查询或甚至修改数据(如果内容提供器允许的话)。例如,Android系统提供的联系人数据就是通过内容提供器共享的。
假设你想从联系人内容提供器中查询联系人的姓名和电话号码,首先,确保你的应用有权限访问联系人。在
AndroidManifest.xml
中添加读取联系人的权限:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
然后,创建一个新的Activity类,比如ContactsActivity
,在这个类中实现查询联系人的功能:
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class ContactsActivity extends Activity {
private static final int REQUEST_READ_CONTACTS_PERMISSION = 1;
private TextView contactsTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
contactsTextView = new TextView(this);
setContentView(contactsTextView);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_READ_CONTACTS_PERMISSION);
} else {
loadContacts();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_READ_CONTACTS_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
loadContacts();
} else {
//权限不允许
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
private void loadContacts() {
StringBuilder builder = new StringBuilder();
//ContentResolver发挥作用
Cursor cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER},
null,
null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
builder.append(name).append(": ").append(phoneNumber).append("\n");
}
cursor.close();
}
contactsTextView.setText(builder.toString());
}
}
这个类首先检查应用是否有读取联系人的权限。如果没有,会请求用户授权;如果已经有权限,就直接加载联系人信息。loadContacts
方法通过getContentResolver()
查询联系人的姓名和电话号码,然后将它们显示在TextView
上。
注意:从Android 6.0 (API level 23) 开始,你需要在运行时请求敏感权限,上面的代码演示了如何请求读取联系人的权限。
最后,别忘了在AndroidManifest.xml
中注册Activity
:
<application ...>
<activity android:name=".ContactsActivity">
...
</activity>
...
</application>