Java version of Android front-end + SpringBoot back-end development and learning

Welcome to learn together!


The book I’m reading is called: The First Line of Code, Second Edition, which can be
read : Android Studio
, because the completion design is Android, so I’m studying, and I don’t write after learning enough to do a complete design. up.

problems encountered

1. Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.
jdk needs to use Java 11. 8 is not allowed.
insert image description hereSolution:
File > Settings > Search Gradle > Select the version we need > Apply > ok
insert image description here
2.Gradle sync failed: Cause: startup failed:
The network is too bad, the address of updating gradle is very slow or wrongly written, making him load the project every time There is no way to update the gradle
insert image description here
download address:
distributionUrl=https://downloads.gradle-dn.com/distributions/gradle-7.0.3-bin.zip
Solution: go to this address to download it, and then run it locally. .
insert image description here
Or find a place with a good network to create a new project. . .

1. Android study notes

1. log log tool

(log is a very useful debugging tool!)
TAG: "Usually a class name, or a custom filter tag"
Log.d(TAG, "information");
search for information in logcat, and you can find log records
insert image description hereHere you can customize the filter
insert image description here

Shortcut:
debug:logd+tab:Log.d();
In addition to debug, there are verbose, info, warn, error
logt+tab can quickly create a local variable of tag
private static final String TAG = "class name";

2. Activity

Basic Usage of Activities

create button

1. Create a new button page file

<?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="wrap_content"
    android:orientation="vertical">

    <Button
        android:id="@+id/button_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="button_1" />
</LinearLayout>

insert image description here2. Load the layout in the activity

setContentView(R.layout.first_layout);//加载页面

insert image description here3. Register the event in the AndroidManifest file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication">

    <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.MyApplication">
        <activity
            android:name=".MainActivity"
            android:label="this is FirstActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

insert image description here

Create Toast - Press the button to pop up Toast

1. Button instantiation
2. Register listener

public class MainActivity extends AppCompatActivity {
    
    
    private static final String TAG = "data";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);//保存当前Activity的状态信息
        setContentView(R.layout.first_layout);//加载页面
    //按钮实例化
        Button button_1 = (Button) findViewById(R.id.button_1);
        Log.d(TAG, "onCreate execute");
    //注册监听器
        button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
                Toast.makeText(MainActivity.this,"you clicked Button_1", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

create menu - use menu menu

insert image description here
1. First define a menu in XML. Create a new menu folder, create a new main.xml;
insert image description here
create an option button in the main.xml file.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/add_item"
        android:title="Add"/>
    <item
        android:id="@+id/remove_item"
        android:title="Remove"/>
</menu>

2. To display the menu, override the onCreateOptionsMenu() method in the Activity.
Rewrite the shortcut key ctrl+o

  • MenuInflater: used to parse the menu layout files defined in the menu directory
  • Inflate(): Find out a layout defined by xml
 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    
    
        MenuInflater inflater = getMenuInflater();//MenuInflater 用来解析定义在menu目录下的菜单布局文件的
        inflater.inflate(R.menu.main, menu);//Inflate()作用就是将xml定义的一个布局找出来
        return true;
    }

Obtain the MenuInflater object through the getMenuInflater() method, and create the current object for the activity by calling the inflate method.

The inflater() method accepts two parameters, the first is which resource file we create to create the menu, here we pass in R.menu.main; the second is used to specify which Menu object our menu items will be added to , here directly use the menu object in the onCreateOptionsMenu() method.

Finally return true to display, if return false it will not be displayed.

3. Define the menu response event
and rewrite onOptionsItemSelected

@Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    
    
        switch (item.getItemId()){
    
    
            case R.id.add_item:
                Toast.makeText(this, "You click add", Toast.LENGTH_SHORT).show();
                break;
            case R.id.remove_item:
                Toast.makeText(this, "You click Remove", Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }

destroy an event

Press back on the phone to
use the code freely: modify the code in the button listener as follows:

button_1.setOnClickListener(new View.OnClickListener(){
    
    
      @Override
      public void onClick(View view) {
    
    
          finish();
      }
});

Use Intent to shuttle between activities

After clicking the application icon, you can only enter the main activity. How to jump from the main activity to other activities?
intent English: purpose intent

Use an explicit Intent to jump

Intent (context, the target activity you want to start)
Open the target activity you want to start under the context
Intent(Context packageContext, Class<?> cls)

button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
				Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                startActivity(intent);
            }
});

Intent(MainActivity.this, SecondActivity.class);
Open the SecondActivity activity in the context of MainActivity

Jump using implicit Intent

Configure the intent-filter filter node in the Manifest.xml configuration file to configure the target activity (jump target)

 <activity
            android:name=".SecondActivity"
            android:exported="false"
            android:label="this is SecondActivity">
            <intent-filter>
                <action android:name="a" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
 </activity>

Just like a secret code, both are a, so they match.
Set up a monitor for the trigger button

        button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
                Intent intent = new Intent("a");//想启动能相应那串字的活动
                startActivity(intent);//启动目标这个对象
            }
        });

Only when the action and category match, can it succeed.

There was only one action just now, and it succeeded because the default category was used. Next, configure the category as well.

 <activity
            android:name=".SecondActivity"
            android:exported="false"
            android:label="this is SecondActivity">
            <intent-filter>
                <action android:name="a" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="b" />
            </intent-filter>
        </activity>
 button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
                Intent intent = new Intent("a");//想启动能相应那串字的活动
                intent.addCategory("b");
                startActivity(intent);//启动目标这个对象
            }
});

More implicit Intent usage

display a web page
 button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
                Intent intent = new Intent(Intent.ACTION_VIEW);//系统内置动作
                intent.setData(Uri.parse("https://www.baidu.com"));
                startActivity(intent);//启动目标这个对象
            }
        });

The action of the intent is Intent.ACTION_VIEW, which is a built-in action of the system.
setData() is used to specify the data that the intent is operating on, and the url is received.

call system dial
button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
                Intent intent = new Intent(Intent.ACTION_DIAL);//想启动能相应那串字的活动
                intent.setData(Uri.parse("tel:10086"));
                startActivity(intent);//启动目标这个对象
            }
        });

Pass data using Intent

Pass data to next activity

Use intent.putExtra (key, value) to store strings, extra English: extras
Use intent.getStringExtra (key) to get strings

(MainActivity) now passes the string hello from FirstActivity to SecondActivity:

 button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
                Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                intent.putExtra("extra_data","hello");
                startActivity(intent);//启动目标这个对象
            }
        });

(SecondActivity) Receive String:

public class SecondActivity extends AppCompatActivity {
    
    

    @Override
    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);
    }   
}
Return data to the previous activity

Start Activity B with the startActivityForResult() method in ActivityA, and return data to A through the setResult() method in B, and A uses the onActivityResult callback function to receive the data.
1. Start Activity B
(MainActivity) with the startActivityForResult() method in ActivityA

button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
                Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                startActivityForResult(intent,1);//启动目标这个对象
            }
        });

When starting another Activity, there are two methods: one is to use startActivity directly, and the other is to use startActivityForResult. The main function of startActivityForResult is that it can return data.

startActivityForResult(Intent intent, int requestCode);

  • The first parameter: an Intent object, which is used to carry the data that will be used in the next interface. Use the putExtra(A,B) method. There are many data types stored here, and all basic types are supported.

  • The second parameter: the request code, in order to distinguish between starting different Intents, or to pass different data, it is used as a different starting identifier. If >=0, requestCode will be returned in onActivityResult() when the Activity ends. In order to determine which Activity the returned data is returned from.

2. In B, return data to A through the setResult() method

(SecondActivity)

 protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_layout);
        Button button_2 = (Button) findViewById(R.id.button_2);
        button_2.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View view) {
    
    
				Intent intent = new Intent();//只是传递数据而已
                intent.putExtra("return_data","hello");//把传递的数据放进去
                setResult(RESULT_OK,intent);//向上一个活动返回数据
                finish();//销毁当前活动
            }
        });
    }  

setResult(RESULT_OK,intent)

  • The first parameter: RESULT_OK is used to return the processing result to the previous activity.
  • The second parameter: intent, used to carry data.

3. A page receives the data returned by B
(MainActivity)

    @SuppressLint("MissingSuperCall")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    
    
        switch (requestCode){
    
    
            case 1:
                if (resultCode == RESULT_OK){
    
    
                    String returnData = data.getStringExtra("return_data");
                    Log.d("MainActivity", returnData);
                }
                break;
            default:
        }
    }

onActivityResult(int requestCode, int resultCode, Intent data)

  • The first parameter: requestCode request code (identification of which activity made the request).
  • The second parameter: resultCode processing result (RESULT_OK).
  • The third parameter: the intent data returned by data.

insert image description here
Return data successfully

If the user returns to page A through the back button of the mobile phone, onBackPressed() can be rewritten:
(SecondActivity)

 @Override
    public void onBackPressed() {
    
    
        Intent intent = new Intent();//只是传递数据而已
        intent.putExtra("return_data","hello 你按了back");//把传递的数据放进去
        setResult(RESULT_OK,intent);//向上一个活动返回数据
        finish();//销毁当前活动
    }

activity life cycle

activity lifetime

The Activity class defines 7 callback methods.

(1) onCreate(): Called when the activity is first created. In this method, complete the initialization of the activity, such as loading the layout, binding events, etc.

(2) onStart(): Called when the activity changes from invisible to visible.

(3) onResume(): Called when the activity is ready to interact with the user. At this point the activity is at the top of the return stack and is in the running state.

(4) onPause(): Called when the system is ready to start or resume another activity. In this method, some resources that destroy the CPU are released to save key data. The execution speed of this method must be fast, otherwise it will affect the use of stack top activities

(5) onStop(): Called when the method is completely invisible. Note the difference between onStop() and onPause().

(6) onDestroy(): Called before the activity is destroyed.

(7) onRestart(): Called before the activity changes from the stopped state to the running state.
The picture is from https://blog.csdn.net/u013476556/article/details/44976947The picture is from https://blog.csdn.net/u013476556/article/details/44976947

Insufficient memory, data recovery

Insufficient memory may recycle stopped activities, temporary data will be lost, and users will be angry.
Solution:
The onSaveInstanceState() callback function is guaranteed to be called before recycling.

 @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
    
    
        super.onSaveInstanceState(outState);
        outState.putString("data_key","临时数据");
    }

This is stored in the Bundle object.
How to recover? Every time there is a Bundle parameter in onCreate(), which is usually null. If it is saved with onSaveInstanceState before recycling, this parameter will bring the previously saved data, and you can modify onCreate to get it out.

 @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_layout);
        if(savedInstanceState != null){
    
    
            String tempData = savedInstanceState.getString("data_key");
            Log.d("SecondActivity", "tempData");
        }
    }

Bundle can also be used to transfer data, first store the data in the Bundle, and then save it in the intent.

Activity launch mode

Modify the launch mode of the activity In AndroidManifest.xml, launchMode="mode"

 <activity
            android:name=".ThirdActivity"
            android:launchMode="standard"
            android:exported="true">
            <intent-filter >
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE"/>
                <data android:scheme="http" />
            </intent-filter>
 </activity>

standard

In the default mode, every time an activity is started, that activity will be pushed onto the stack, and he doesn't care whether the activity already exists in the stack, and a new instance will be created every time the activity is started.

singleTop

The singleton at the top of the stack, when the activity is started, it is found that the top of the return stack is this activity, and no new instance will be created. If the top of the stack is not the activity, a new instance will still be created.

singleTask

When starting an activity, check whether there is an activity instance, if there is, use this instance directly, and then pop all the activities above this activity out of the stack, if not, create a new instance.

singleInstance

Enable a separate new stack to manage this activity, solving the shared activity instance problem.
The destruction activity also destroys the main stack first, and then refreshes the stack.

Skill

Know which is currently active

In the onCreate of the current activity write:

Log.d("MainActivity", getClass().getSimpleName());

can be seen in the logs.

Exit the program anytime, anywhere

If there are many activities in the startup stack, and now you want to exit the program directly, pressing home is useless (just hangs), you can create a new ActivityCollector class as the activity manager:

package com.example.myapplication;
import android.app.Activity;
import java.util.ArrayList;
import java.util.List;

public class ActivityCollector {
    
    
    public static List<Activity> activities = new ArrayList<>();
    public static void addActivity(Activity activity){
    
    
        activities.add(activity);
    }
    public static void removeActivity(Activity activity){
    
    
        activities.remove(activity);
    }
    public static  void finishAll(){
    
    
        for (Activity activity:activities) {
    
    
            if(! activity.isFinishing()){
    
    
                activity.finish();
            }
        }
        android.os.Process.killProcess(android.os.Process.myPid());//杀死当前进程
    }
}

Each activity onCreate addsActivity (this), and onDestory removeActivity (this).
Call finish when you want to exit the activity.

Best way to start a campaign

MainActivity wants to start SecondActivity, but it doesn't know what the key of the value is, the solution:
(SecondActivity)

 //封装参数启动当前活动
    public static void actionStart(Context context,String data1,String data2){
    
    
        Intent intent = new Intent(context,SecondActivity.class);
        intent.putExtra("data1",data1);
        intent.putExtra("data2",data2);
        context.startActivity(intent);
    }

(MainActivity)

 button_1.setOnClickListener(new View.OnClickListener(){
    
    
            @Override
            public void onClick(View view) {
    
    
                SecondActivity.actionStart(MainActivity.this,"data1","data2");
            }
        });

3. UI

Write it in detail at the end, just check what you want to use.

control

Red is
insert image description herethe image source of commonly used controls: https://blog.csdn.net/wufen12334/article/details/53072538

TextView

display text information

Button

button

EditText

Input and compile content

ImageView

Show pictures

ProgressBar

A progress bar is displayed, indicating that the program is loading some data.

AlertDialog

A dialog box pops up on the current page. This dialog box is placed on top of all interface elements, which can block the interaction ability of other controls, and can warn, prompt, etc.

ProgressDialog

A dialog box pops up on the interface, which can block the interaction ability of other controls, and display a progress bar, indicating that the current operation is time-consuming, please wait.

custom control

basic layout

LinearLayout linear layout

RelativeLayout relative layout

FrameLayout frame layout

All controls are placed in the upper left corner by default

percentage layout

Arbitrary ratio split layout

Open source UI framework

Side-Menu.Android classification side menu

https://github.com/Yalantis/Side-Menu.Android
insert image description here

AndroidSwipeLayout sliding Layout

Sliding Layout supports single View, ListView, GridView.
Project address:
https://github.com/daimajia/AndroidSwipeLayout
insert image description here

Android function practice

1. Display list information in fragment

Follow this article to learn

Question: When writing a repository, use okhttp to transfer parameters from the background and then encapsulate them into beans and then return, return first and then adjust the thread, so it will always be empty.
Solution::
Thread: The main thread waits for the child thread to finish executing before executing the solution

2. The same button will only respond to one click event within 1 second

public abstract class OnMultiClickListener implements View.OnClickListener{
    
    
    // 两次点击按钮之间的点击间隔不能少于1000毫秒
    private static final int MIN_CLICK_DELAY_TIME = 1000;
    private static long lastClickTime;

    public abstract void onMultiClick(View v);

    @Override
    public void onClick(View v) {
    
    
        long curClickTime = System.currentTimeMillis();
        if((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
    
    
            // 超过点击间隔后再将lastClickTime重置为当前点击时间
            lastClickTime = curClickTime;
            onMultiClick(v);
        }
    }
}
btn.setOnClickListener(new OnMultiClickListener() {
    
    
            @Override
            public void onMultiClick(View v) {
    
    
                // 进行点击事件后的逻辑操作
            }
        });

Nested ListView in ScrollView

Nested ListView in ScrollView

Jump between fragments

Followed by this
and this

timer

timer

countdown jump

Countdown is implemented in two ways

stepped on pit

white space at the top

white space at the top

To be continued...

2. Server

The idea used, springboot
1. To build a springboot project, this article is enough .
It is set up like this, and then you can write the interface on the server side.
insert image description here
2. Next, build dao, service, etc. to complete the login function
What I read is this article, which was written following the establishment of the UserBean file.
Note that there are some mistakes in this article, just change it according to the following.

The original code in Demo1ApplicationTests in the test class is @RunWith(SpringRunner.class) reporting an error, use @MapperScan("com.example.test.mapper") instead; spring.datasource.driver-class-name=com.mysql in application.properties .cj.jdbc.Driver, add cj; private UserMapper userMapper in the UserServiceImpl class, the original code is @Autowired, use @Resource instead after reporting an error; UserMapper class uses @Repository, getInfo should be UserBean getInfo(@Param(“name”) String name, @Param("password")String password); A piece of data "1,a,a" has been added to the user table

The test is successful:
insert image description here
shortcut key
alt+insert: create a get set
and then I want to separate
vue+springboot with the front and back ends

3. Front-end and back-end communication

Follow this video to learn: Android APP project front-end communication connection android studio and springboot as an example Postman usage method review

3.1 Learn the simplest one first, pass the string in the past, and return the string.

In build.gradle insert image description hereadd

implementation 'com.squareup.okhttp3:okhttp:4.4.1'

Link to server:

new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    //创建http客户端
                    OkHttpClient client = new OkHttpClient();
                    //创建表单体(参数)
                    FormBody.Builder params = new FormBody.Builder();
                    params.add("id", "1806050107");
                    params.add("password", "123456");

                    //创建http请求
                    Request request = new Request.Builder()
                            .url("http://192.168.43.73:8080/PartyMemberLoginIn")
                            .post(params.build())
                            .build();
                    //执行发送的指令
                    Response response = client.newCall(request).execute();
                    //回应
                    String responseData = response.body().string();
                    System.out.println(responseData);
                    userName.postValue(responseData);
                }catch (Exception e){
    
    
                    e.printStackTrace();
                }
        }
        }).start();

The mistake I made :
No error was reported, and there was no response because I forgot to write start.
An error was reported, because I implemented two versions of okhttp3

The SpringBoot service is written like this:
insert image description here


@Controller
public class LoginInController {
    
    
    //将Service注入Web层
    @Autowired
   private UserService userService;

    @ResponseBody
    @RequestMapping(value = "/PartyMemberLoginIn",method = RequestMethod.POST)
    public String PartyMemberLoginIn(@RequestParam String id,@RequestParam String password){
    
    
        try {
    
    
            UserBean userBean = userService.PartyMemberLoginIn(id,password);
            if(userBean!=null){
    
    
                return "success";
            }else{
    
    
                return "登录失败";
            }
        }catch (Exception e){
    
    
            return "服务器出错了";
        }
    }
}

Among them, @ResponseBody is the value of return, not an xml page, you must add
@RequestParam, which is the parameter to be passed
Success:
insert image description hereuse postman to test the back-end interface, free, no money, you can download it from the official website.

Randomly query 5 pieces of data in the mysql database for testing sql writing

SELECT * FROM employees ORDER BY RAND() LIMIT 5;

Guess you like

Origin blog.csdn.net/qq_30738155/article/details/122518974