主頁 > 移動端開發 > 胖葵酒店管理系統(android客戶端+javaweb服務端+騰訊云服務器+騰訊云資料庫)

胖葵酒店管理系統(android客戶端+javaweb服務端+騰訊云服務器+騰訊云資料庫)

2020-12-03 10:08:32 移動端開發

胖葵酒店管理系統app

完整專案已上傳github,鏈接在文章下面

先看效果圖:

登錄:

在這里插入圖片描述

主頁面(點擊右上角圖示進入個人中心頁面):

在這里插入圖片描述

經理模塊(客房管理模塊和員工管理模塊與經理管理模塊類似,員工管理模塊還包括增加和洗掉員工功能):

在這里插入圖片描述

修改經理資訊:

在這里插入圖片描述

添加員工:

在這里插入圖片描述

洗掉員工:

在這里插入圖片描述

財務查詢模塊:

在這里插入圖片描述

個人中心頁面:

在這里插入圖片描述

修改密碼:

在這里插入圖片描述

忘記密碼:

在這里插入圖片描述

開發工具

客戶端:Android Studio 4.1.0

服務端:IDEA 2020.1

網路通信框架:Android Volley

短信驗證平臺:MobTech SMSSDK

tomcat 9.0

jdk 13.0

資料庫:騰訊云資料庫Mysql 5.7

服務器:騰訊云服務器Windows Server 2012 R2

客戶端app

專案框架

在這里插入圖片描述

說明:
activity(從上到下)

1、基礎activity,定義頂部導航欄,供其他頁面繼承使用

2、修改員工,包括增刪改查功能

3、修改經理,包括修改和查看經理資訊功能

4、修改密碼,

5、修改客房,包括修改和查看客房資訊功能

6、忘記密碼,包括對用戶輸入手機號是否與資料庫預留的匹配驗證,以及短信驗證功能

7、登錄,

8、查看員工資訊資料表

9、查看經理資訊資料表

10、查看財務資訊資料表

11、查看客房資訊資料表

12、主頁面

13、個人中心頁面,包括修改密碼和退出登錄功能

14、歡迎頁面

constants

1、保存用戶登錄資訊,用于自動登錄功能

help

1、用戶自動登錄功能

utils

1、SharedPreferences工具

views

1、輸入樣式,供其他頁面呼叫

主要功能頁

與服務端建立通信的頁面包括登錄頁面、經理資訊管理模塊、客房資訊管理模塊、員工資訊管理模塊、修改密碼模塊,下面以登錄頁面為例進行說明,其他頁面可以下載代碼自己看,

登錄模塊代碼如下:

package com.example.hotelmanager.activities;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.blankj.utilcode.util.RegexUtils;
import com.example.hotelmanager.R;
import com.example.hotelmanager.help.UserHelp;
import com.example.hotelmanager.utils.SPUtils;
import com.example.hotelmanager.views.InputView;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class Login extends BaseActivity {

    private InputView mInputId, mInputPassword;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        initView();
    }

    //初始化View
    private void initView() {
        initNavBar(false, "登錄", false);

        mInputId = findViewById(R.id.input_phone);
        mInputPassword = findViewById(R.id.input_password);
    }


    //登錄點擊事件
    public void onCommitClick(View v) {
        String id = mInputId.getInputStr();
        String password = mInputPassword.getInputStr();

        //驗證輸入是否合法
        if (!validateLogin(this, id, password)) {
            return;
        }

        SignInRequest(id, password);

    }

    //驗證用戶輸入合法性
    public static boolean validateLogin(Context context, String phone, String password) {
        if (!RegexUtils.isMobileExact(phone)) {
            Toast.makeText(context, "用戶id無效", Toast.LENGTH_SHORT).show();
        }

        if (TextUtils.isEmpty(password)) {
            Toast.makeText(context, "請輸入密碼", Toast.LENGTH_SHORT).show();
            return false;
        }


        //保存用戶登錄標記
        boolean isSaved = SPUtils.saveUser(context, phone);
        if (!isSaved) {
            Toast.makeText(context, "系統錯誤,請稍后重試", Toast.LENGTH_SHORT).show();
            return false;
        }

        UserHelp.getInstance().setPhone(phone);
        
        return true;
    }

    public void onForgetClick(View view) {
        String id = mInputId.getInputStr();

        //驗證輸入是否合法
        if (!validateForget(this, id)) {
            return;
        }
        UserHelp.getInstance().setPhone(id);
        //startActivity(new Intent(this,ChangePassword.class));
        ForgetRequest(id,"****");
    }

    private boolean validateForget(Login login, String phone) {
        if (!RegexUtils.isMobileExact(phone)) {
            Toast.makeText(this, "手機號無效", Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    public void SignInRequest(final String username, final String password) {
        //請求地址
        String url = "http://132.232.81.77:8080/HotelServer/loginServlet";
        String tag = "Login";
        //取得請求佇列
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        //防止重復請求,所以先取消tag標識的請求佇列
        requestQueue.cancelAll(tag);
        //創建StringRequest,定義字串請求的請求方式為POST(省略第一個引數會默認為GET方式)
        final StringRequest request = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject jsonObject = (JSONObject) new JSONObject(response).get("params");
                            String result = jsonObject.getString("Result");
                            if (result.equals("TheUserDoesNotExist")) {
                                Toast.makeText(Login.this, "用戶不存在", Toast.LENGTH_SHORT).show();
                            } else if (result.equals("PasswordError")) {
                                Toast.makeText(Login.this, "密碼錯誤", Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(Login.this, "登錄成功", Toast.LENGTH_SHORT).show();
                                Intent intent = new Intent(Login.this, MainActivity.class);
                                intent.putExtra("username", username);
                                startActivity(intent);
                                finish();
                            }
                        } catch (JSONException e) {
                            //做自己的請求例外操作,如Toast提示(“無網路連接”等)
                            Log.e("TAG", e.getMessage(), e);
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                //做自己的回應錯誤操作,如Toast提示(“請稍后重試”等)
                Log.e("TAG", error.getMessage(), error);
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("username", username);
                params.put("password", password);
                return params;
            }
        };

        //設定Tag標簽
        request.setTag(tag);

        //將請求添加到佇列中
        requestQueue.add(request);
    }

    public void ForgetRequest(final String username, final String password){
        //請求地址
        String url = "http://132.232.81.77:8080/HotelServer/loginServlet";
        String tag = "Login";
        //取得請求佇列
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        //防止重復請求,所以先取消tag標識的請求佇列
        requestQueue.cancelAll(tag);
        //創建StringRequest,定義字串請求的請求方式為POST(省略第一個引數會默認為GET方式)
        final StringRequest request = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject jsonObject = (JSONObject) new JSONObject(response).get("params");
                            String result = jsonObject.getString("Result");
                            if (result.equals("TheUserDoesNotExist")) {
                                Toast.makeText(Login.this, "用戶不存在", Toast.LENGTH_SHORT).show();
                            }else {
                                Toast.makeText(Login.this, "用戶驗證通過", Toast.LENGTH_SHORT).show();
                                Intent intent = new Intent(Login.this, ForgetPassword.class);
                                intent.putExtra("username",username);
                                startActivity(intent);
                            }
                        } catch (JSONException e) {
                            //做自己的請求例外操作,如Toast提示(“無網路連接”等)
                            Log.e("TAG", e.getMessage(), e);
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                //做自己的回應錯誤操作,如Toast提示(“請稍后重試”等)
                Log.e("TAG", error.getMessage(), error);
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("username", username);
                params.put("password", password);
                return params;
            }
        };

        //設定Tag標簽
        request.setTag(tag);

        //將請求添加到佇列中
        requestQueue.add(request);
    }

}
登陸部分

傳入兩個引數,分別是用戶輸入的id和密碼,請求與服務端建立連接,以Json格式傳給服務端處理,服務端驗證id與密碼是否匹配,將處理結果回傳給客戶端,根據接收到的結果將相應的資訊反饋到螢屏提示用戶

忘記密碼部分

其實這里只需要傳入一個引數,就是用戶id,但為了偷懶我直接復制了登陸部分的代碼,不必在意這些細節,

同樣請求與服務端建立連接,服務端驗證用戶輸入的id是否存在于資料庫中,將結果回傳給客戶端,

關鍵技術點

Android Volley 通信框架

Volley可以說把異步網路通信和網路圖片的加載都封裝于一身,他讓開發者們更輕松地進行HTTP通信和加載網路上的圖片,Volley除了簡單易用之外,在性能上也進行了大幅度的調整,它的設計目標就是非常適合進行資料量不大且通信頻繁的網路操作,所以并不適合對大資料量的網路操作,比如下載檔案,

如何使用:

1、創建一個android專案

2、匯入volley包

3、宣告網路權限

4、發送請求

參考博客:

https://blog.csdn.net/Mr_Megamind/article/details/74048891

https://blog.csdn.net/perArther/article/details/50856394?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.control

webview網頁顯示

WebView的最簡單的使用方式即是直接顯示網頁內容,有以下兩個步驟:

  1. 在布局檔案中添加WebView控制元件;
  2. 在代碼中讓WebView控制元件加載顯示網頁,

參考博客:https://blog.csdn.net/weixin_40438421/article/details/85700109

短信驗證服務

這里短信驗證碼服務采用MobTech平臺的SMSSDK短信驗證服務,附上平臺鏈接:https://new.dashboard.mob.com/#/SMSSDK,按照教程在平臺創建應用,會得到一個app key和app secret,如下:

在這里插入圖片描述

在android studio完成相應的配置即可使用,附上配置教程:https://www.mob.com/wiki/detailed?wiki=SMSSDK_for_Android_kuaisujicheng&id=23

我的配置如下:

在project的build.gradle里:

在這里插入圖片描述

在module的build.gradle里加上:

在這里插入圖片描述

服務端

專案框架

在這里插入圖片描述
在這里插入圖片描述

說明:
bean(封裝資料,是資料庫中表的映射)

1、員工表

2、經理資訊表

3、客房表

4、經理id、密碼表

dao(實作資料的持久化操作,如增刪改查)

1、員工資訊操作

2、經理資訊操作

3、客房資訊操作

4、經理密碼操作

service(業務邏輯的實作)

上面四個Impl分別實作下面四個interface封裝的功能集合

util(工具)

1、連接資料庫

2、讀取組態檔

web.servlet(服務連接器,前后端通信)

1、添加員工

2、修改員工資訊

3、修改經理資訊

4、修改密碼

5、修改客房資訊

6、洗掉員工

7、登錄(包括忘記密碼)

config

資料庫組態檔

四個.jsp檔案

1、查看員工資料表資訊

2、查看經理資料表資訊

3、查看財務資料表資訊

4、查看客房資料表資訊

Style.css

jsp樣式效果

下面主要說一下連接騰訊云資料庫和servlet部分

組態檔如下:

url=jdbc:mysql://cdb-fmhwq8ww.cd.tencentcdb.com:10074/hotel?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
driverClass=com.mysql.jdbc.Driver
user=root
password=b980227l

cdb-fmhwq8ww.cd.tencentcdb.com:10074/hotel 這是云資料庫的外網地址和介面,hotel是專案資料庫

以登錄為例說明

.servlet

package PKhotel.web.servlet;

import PKhotel.bean.User;
import PKhotel.service.Impl.UsersServiceImpl;
import PKhotel.util.DButil;
import net.sf.json.JSONObject;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@WebServlet(name="loginServlet")
public class LoginServlet extends HttpServlet {
    DButil dButil = new DButil();
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //設定相應內容型別
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        try(PrintWriter out = response.getWriter()){
            String username = request.getParameter("username").trim();
            String password = request.getParameter("password").trim();
            UsersServiceImpl service = new UsersServiceImpl();
            int verigyResult = service.verifyLogin(new User(username,password),dButil);

            Map<String,String> params = new HashMap<>();
            JSONObject jsonObject = new JSONObject();

            if(verigyResult == -1){
                params.put("Result","TheUserDoesNotExist");
            }else if(verigyResult == 0){
                params.put("Result","PasswordError");
            }else if(verigyResult == 1){
                params.put("Result","CorrectPassword");
            }

            jsonObject.put("params",params);
            out.write(jsonObject.toString());

        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

接收客戶端傳來的id和密碼,呼叫service中的verifyLogin函式處理,將結果回傳給客戶端

verifyLogin函式如下:

@Override
public int verifyLogin(User u, DButil dButil) {
    List<User> userList = null;
    String username = u.getUsername();
    String password = u.getPassword();
    try{
        userList = userDao.queAll(dButil);
    }catch (Exception e){
        e.printStackTrace();
    }
    boolean hasUser = false;
    boolean rightPass = false;
    for(User user:userList){
        if(user.getUsername().equals(username)){
            hasUser = true;
            if(user.getPassword().equals(password)){
                rightPass = true;
            }
            break;
        }
    }
    if(!hasUser) return -1;//無該用戶
    else if(!rightPass) return 0;//有該用戶,但是密碼輸入錯誤
    return 1;//有該用戶,且密碼輸入正確
}

遍歷資料庫表,驗證是否有該用戶以及密碼與用戶是否匹配

坑點

web專案無法加載css檔案解決方法:https://blog.csdn.net/YOUYOU0710/article/details/106267793/?utm_medium=distribute.pc_relevant.none-task-blog-title-3&spm=1001.2101.3001.4242

專案部署

IDEA將專案打包成war包:https://blog.csdn.net/weixin_43716048/article/details/108639475?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control

將war包部署在云服務器:https://blog.csdn.net/zhangjin2024/article/details/101173520?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

查看資料表資訊

http://132.232.81.77:8080/HotelServer/lookmanager.jsp
http://132.232.81.77:8080/HotelServer/lookorder.jsp
http://132.232.81.77:8080/HotelServer/lookemployees.jsp
http://132.232.81.77:8080/HotelServer/lookroom.jsp

完整專案鏈接

github:https://github.com/guyuanjunxi/PKHotelManager

csdn:https://download.csdn.net/download/qq_41117896/13208830

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/229226.html

標籤:其他

上一篇:新手Android studio的安裝及初步使用

下一篇:如何加載100M的圖片卻不撐爆記憶體,一張 100M 的大圖,如何預防 OOM?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more