【版本】
当前版本号v20230927
版本 | 修改说明 |
---|---|
v20230927 | 移除一些无用的import代码,避免造成编译错误 |
v20220929 | 修正一个缺失的图片 |
v20220915 | 删减部分代码,避免出现编译错误 |
v20220823 | 初始化版本 |
【实验名称】 实验3.1 Java 多线程编程模型
【实验目的】
- 掌握 Java 的简单的多线程编程
【实验环境】
- 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
- 计算机可以访问互联网。
- 内存:至少6G
- 硬盘:至少空余20G
- JDK 8或以上
- IntelliJ IDEA
【实验要求】
- 基于现有的代码进行完善,实现甲和乙2个单独的线程运行,其中甲进行倒数计数,乙进行正数计数。
【实验步骤】
安装JDK8,打开IDEA,创建一个Java项目。
创建类
ThreadTest
,代码如下所示。
package iot.app.thread;
public class ThreadTest {
public static void main(String[] args){
//甲从7数到1
new Thread(new DecCounter("甲",7)).start();
//乙从1数到7
new Thread(new AscCounter("乙",7)).start();
}
public static class DecCounter implements Runnable{
private String name;
private int num;
public DecCounter(String name,int num){
this.name=name;
this.num=num;
}
@Override
public void run() {
for(int i=num;i>0;i--) {
System.out.println(name+":"+i);
try {
Thread.sleep(1000);//睡1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static class AscCounter implements Runnable{
private String name;
private int num;
public AscCounter(String name,int num){
this.name=name;
this.num=num;
}
@Override
public void run() {
//TODO:请完善这里的代码,实现正数计数。
}
}
}
- 完善内部类
AscCounter
的代码,实现正数计数(参考DescCounter
)。
【实验名称】 实验3.2 Java 编写观察者模式例子
【实验目的】
- 掌握使用 Java 编写观察者模式
【实验环境】
- 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
- 计算机可以访问互联网。
- 内存:至少6G
- 硬盘:至少空余20G
- JDK 8或以上
- IntelliJ IDEA
【实验要求】
- 基于现有的代码进行完善,实现每当报社(目标对象)发行新的报纸,甲和乙两位读者(观察者)都能够立刻收到通知。
【实验步骤】
安装JDK8,打开IDEA,创建一个Java项目。
请完善以下代码中的
PaperOffice
的run
方法
项目架构
src
|-iot.app.observer
|- Observer
|- PaperOffice
|- Reader
|- Subject
Observer.java
package iot.app.observer;
/**
* 观察者
*/
public interface Observer {
/**
* 观察目标对象
* @param sub
*/
void observe(Subject sub);
/**
* 更新目标对象数据
*/
void update();
}
PaperOffice.java
package iot.app.observer;
import java.util.LinkedList;
import java.util.List;
/**
* 报社
*/
public class PaperOffice implements Subject,Runnable {
private String paper;
private List<Observer> obsList=new LinkedList<>();
@Override
public void attach(Observer obs) {
obsList.add(obs);
}
@Override
public void notifyObservers() {
for(Observer obs:obsList){
obs.update();
}
}
@Override
public Object getData() {
return paper;
}
public void setPaper(String paper) {
this.paper = paper;
}
@Override
public void run() {
String[] ps=new String[]{"周一晚报","周二晚报","周三晚报","周四晚报","周五晚报","周六晚报","周日晚报"};
int i=0;
while(i<ps.length){
//TODO:请完善此方法
}
}
public static void main(String[] args){
PaperOffice po=new PaperOffice();
Reader a=new Reader("甲");//读者甲
Reader b=new Reader("乙");//读者乙
a.observe(po);//甲观察报社
b.observe(po);//乙观察报社
new Thread(po).start();
}
}
Reader.java
package iot.app.observer;
/**
* 读者
*/
public class Reader implements Observer{
private Subject sub;
public String name;
public Reader(String name) {
this.name=name;
}
/**
* 观察
* @param sub
*/
@Override
public void observe(Subject sub) {
this.sub=sub;
sub.attach(this);
}
/**
* 更新目标对象数据
*/
@Override
public void update() {
System.out.println(name+"收到"+sub.getData());
}
}
Subject.java
package iot.app.observer;
/**
* 目标对象
*/
public interface Subject {
/**
* 关联观察者
* @param obs
*/
void attach(Observer obs);
/**
* 通知所有观察者
*/
void notifyObservers();
/**
* 获取数据
* @return
*/
Object getData();
}
【实验名称】 实验3.3 MVVM架构实现
【实验目的】
- 掌握 Android 的MVVM架构设计
【实验环境】
- 一台运行 64 位版本的 Windows(8、10 或 11)、Linux、macOS(10.14 Mojave 或更高版本)或 Chrome 操作系统的计算机。
- 计算机可以访问互联网。
- 内存:至少6G
- 硬盘:至少空余20G
- JDK 8或以上
- Android Studio
【实验要求】
- 创建新的项目 smarthome,实现登录界面的双向数据的绑定。
【实验步骤】
打开Android Studio,新建一个名为 smarthome 的项目。
打开
iot_app_smarthome\app\build.gradle
,注意在原有android
配置项内加入以下配置。
android {
...
//开启数据绑定
dataBinding {
enabled = true
}
}
- 新增
LoginActivity
,加入用户名
输入框组件、密码
输入框组件、登录
按钮和填充
按钮。
LoginActivity.java
- 项目路径,其中
iot.app.smarthome.ui.login
是包路径。
iot_app_smarthome
|- app
|-src
|- main
|- java
|- iot.app.smarthome.ui.login
|- LoginActivity.java
- 内容
package iot.app.smarthome.ui.login;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import iot.app.smarthome.R;
import iot.app.smarthome.databinding.ActivityLoginBinding;
import iot.app.smarthome.vm.login.LoginViewModel;
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
private ActivityLoginBinding activityLoginBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//从视图中获取绑定对象
activityLoginBinding =DataBindingUtil.setContentView(this, R.layout.activity_login);
//设置绑定对象的生命周期拥有者为本对象
activityLoginBinding.setLifecycleOwner(this);
//创建 ViewModel
loginViewModel = new ViewModelProvider(this).get(LoginViewModel.class);
//绑定对象设值 ViewModel
activityLoginBinding.setLoginViewModel(loginViewModel);
Button loginBtn=(Button)findViewById(R.id.loginBtn);
loginBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
//输入的用户名,展示ViewModel对应的用户名属性,查看是否一致。
Toast.makeText(LoginActivity.this,"ViewModel username:"+loginViewModel.getLoginVo().username.get(),Toast.LENGTH_SHORT).show();
}
});
//自动填充按钮绑定点击事件
Button fillBtn=(Button)findViewById(R.id.fillBtn);
fillBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
//给ViewModel 的username设值,观察视图的用户名是否绑定对应的值
loginViewModel.getLoginVo().username.set("zhangsan");
}
});
}
}
activity_login.xml
- 项目路径
iot_app_smarthome
|- app
|-src
|- main
|- res
|- layout
|- activity_login.xml
- 内容
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="loginViewModel"
type="iot.app.smarthome.vm.login.LoginViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.login.LoginActivity">
<LinearLayout
android:layout_width="409dp"
android:layout_height="729dp"
android:orientation="vertical"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
android:textAlignment="center" />
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="用户名"
android:text="@={loginViewModel.loginVo.username}"
android:inputType="textPersonName" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:text="@={loginViewModel.loginVo.password}"
android:hint="密码"
android:inputType="textPassword" />
<Button
android:id="@+id/loginBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录" />
<Button
android:id="@+id/fillBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="填充" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
- 新增
LoginViewModel
。
LoginViewModel.java
- 项目路径,其中
iot.app.smarthome.vm.login
是包路径。
iot_app_smarthome
|- app
|-src
|- main
|- java
|- iot.app.smarthome.vm.login
|- LoginViewModel.java
- 内容
package iot.app.smarthome.vm.login;
import androidx.lifecycle.ViewModel;
import iot.app.smarthome.model.login.ObservableLoginInfo;
public class LoginViewModel extends ViewModel {
private ObservableLoginInfo loginVo;
public LoginViewModel(){
loginVo=new ObservableLoginInfo();
}
public ObservableLoginInfo getLoginVo() {
return loginVo;
}
public void setLoginVo(ObservableLoginInfo loginVo) {
this.loginVo = loginVo;
}
}
- 新增
ObservableLoginInfo
。ObservableField 类型的值可以绑定界面组件。
- 项目路径,其中
iot.app.smarthome.model.login
是包路径。
ObservableLoginInfo.java
iot_app_smarthome
|- app
|-src
|- main
|- java
|- iot.app.smarthome.model.login
|- ObservableLoginInfo.java
- 内容
package iot.app.smarthome.model.login;
import androidx.databinding.ObservableField;
public class ObservableLoginInfo {
public ObservableField<String> username=new ObservableField<>();
public ObservableField<String> password=new ObservableField<>();
}
- 构建项目,发布到模拟器运行,观察是否数据实现了双向绑定。