Android開發初體驗

来源:http://www.cnblogs.com/mdx9626/archive/2017/09/16/7499029.html
-Advertisement-
Play Games

本文通過開發一個應用來學習Android基本概念及構成應用的UI組件。 開發的應用名叫GeoQuiz,它能給出一道道地理知識問題。用戶點擊true或false按鈕回答問題,應用即時做出反饋 第一步請先自行創建一個新項目,目錄如下 1. 用戶界面設計 在XML文件(activity_quiz.xml) ...


本文通過開發一個應用來學習Android基本概念及構成應用的UI組件。
開發的應用名叫GeoQuiz,它能給出一道道地理知識問題。用戶點擊true或false按鈕回答問題,應用即時做出反饋

第一步請先自行創建一個新項目,目錄如下

1. 用戶界面設計

  • 在XML文件(activity_quiz.xml)中定義組件
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/question_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp" />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/true_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/true_button"/>
        <Button
            android:id="@+id/false_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/false_button"/>
    </LinearLayout>
    <Button
        android:id="@+id/cheat_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/cheat_button"/>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/pre_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/pre_button"
            android:drawableLeft="@drawable/arrow_left"/>
        <ImageButton
            android:id="@+id/next_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/arrow_right"
            android:contentDescription="@string/next_button"/>
    </LinearLayout>
</LinearLayout>

activity_quiz.xml 效果圖

  • 創建字元串資源

最好不要硬編碼設置組件的文本信息,如:android:text="True"。較好的做法是將文字內容放置在獨立的字元串資源XML文件中,然後引用它們,如:android:text="@string/true_button"

找到app/res/values目錄,打開string.xml文件
添加字元串資源

<resources>
    <string name="app_name">GeoQuiz</string>
    <string name="true_button">True</string>
    <string name="false_button">False</string>
    <string name="pre_button">Pre</string>
    <string name="next_button">Next</string>
    <string name="correct_toast">Correct!</string>
    <string name="incorrect_toast">Incorrect!</string>
    <string name="question_oceans">The Pacific Ocean is larger than
the Atlantic Ocean.</string>
    <string name="question_mideast">The Suez Canal connects the Red Sea
and the Indian Ocean.</string>
    <string name="question_africa">The source of the Nile River is in Egypt.</string>
    <string name="question_americas">The Amazon River is the longest river in the Americas.</string>
    <string name="question_asia">Lake Baikal is the world\'s oldest and deepest
freshwater lake.</string>
    <string name="warning_text">Are you sure you want to do this?</string>
    <string name="show_answer_button">SHOW ANSWER</string>
    <string name="cheat_button">CHEAT!</string>
    <string name="judgment_toast">Cheating is wrong.</string>
    <string name="fist_page">This is the first page!</string>
</resources>

2. 從佈局XML到視圖對象

  • activity子類的實例創建後,onCreate(Bundle)方法會被調用,同時需要獲取並管理用戶界面,可再調用setContentView(int layoutResID),根據傳入的佈局資源ID參數,生成指定佈局視圖並將其放在屏幕上,佈局文件包含的組件也隨之以各自的屬性定義完成實例化。
public class QuizActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_quiz);
    }
}
  • 資源和資源ID
  1. 使用資源ID在代碼中獲取相應的資源。activity_quiz.xml佈局的資源ID為R.layout.activity_quiz。
  2. 應用當前所有的資源放置在R.java文件中。切換至Project視圖,展開目錄app/build/generated/source/r.debug即可看到。R.java文件在Android項目編譯過程中自動生成,修改佈局或字元串等資源後,需再次運行應用,才會得到更新。
  3. 為需要的組件添加資源ID。如:android:id="@+id/idName"
  • 組件的應用
    private Button mTrueButton;//在activity_quiz.java添加成員變數
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ......
         mTrueButton=(Button)findViewById(R.id.true_button);//引用組件
         mTrueButton.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                //設置監聽事件
            }
        });
    }
   

3. 創建提示消息

Android的toast是用來通知用戶的簡短彈出消息。調用Toast類的以下方法可創建toast:

public static Toast makeText(Context context,int resId,int durattion)
  • Context參數通常是Activity的一個實例(Activity本身就是Context的子類)。
  • 第二個參數是toast要顯示字元串消息的資源ID。
  • 第三個參數用來指定toast消息的停留時間。通常是Toast常量中的一個。
//舉個例子來說
Toast.makeText(QuizActivity.this,R.string.incorrect_toast,Toast.LENGTH_SHORT).show();

4. Android與MVC設計模式

  • 應用對象按模型、控制器和視圖的類別分為三部分。Android應用基於模型-
    控制器-視圖(Model-View-Controller,MVC)的架構模式進行設計。MVC設計模式表明,應用的任何對象,歸根結底都屬於模型對象、視圖對象以及控制對象中的一種。

  • 我們使用 QuizActivity 創建 Question 數組對象。繼而通過與 TextView 以及三個 Button 的交互,在屏幕上顯示地理知識問題,並根據用戶的回答作出反饋,如圖2-4所示。

  • 模型層 Question類代碼
public class Question {
    private int mTextResId;//保存地理知識問題字元串的資源ID。資源ID總是int類型
    private boolean mAnswerTrue;//問題答案

    public Question(int textResId,boolean answerTrue){
        mTextResId=textResId;
        mAnswerTrue=answerTrue;
    }

    public int getTextResId() {
        return mTextResId;
    }

    public void setTextResId(int textResId) {
        mTextResId = textResId;
    }

    public boolean isAnswerTrue() {
        return mAnswerTrue;
    }

    public void setAnswerTrue(boolean answerTrue) {
        mAnswerTrue = answerTrue;
    }
}

對於有首碼m的成員變數生成getter與setter方法

首先,配置Android Studio識別成員變數的 m 首碼。
打開Android Studio首選項對話框(Mac用戶選擇Android Studio菜單,Windows用戶選擇File →
Settings菜單)。分別展開Editor和Code Style選項,在Java選項下選擇CodeGeneration選項頁。在Naming表單中,選擇Fields行,添加m作為fields的首碼。若要添加靜態變數首碼s,則添加 s 作為Static Fields的首碼。如下圖。

  • 控制器層QuizActivity.java
public class QuizActivity extends AppCompatActivity {
    private ImageButton mNextButton;

    private TextView mQuestionTextView;

    private Question[] mQuestionBank=new Question[]{
            new Question(R.string.question_oceans,true),
            new Question(R.string.question_mideast,false),
            new Question(R.string.question_africa,false),
            new Question(R.string.question_americas,true),
            new Question(R.string.question_asia,true)
    };

    private int mCurrentIndex=0;
    
}

5. 添加圖片資源

1.將圖片添加到drawable對應目錄中,尾碼名為.png、.jpg、.gif的文件都會自動獲得資源ID
  • mdpi:中等像素密度屏幕(約160dpi)
  • hdpi:高等像素密度屏幕(約240dpi)
  • xhdpi:超高像素密度屏幕(約320dpi)
  • xxdpi:超超高像素密度屏幕(約480dpi)
2. 在XML文件中引用資源
  • 為next按鈕增加圖片(activity_quiz.xml)
 <Button
          android:id="@+id/next_button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/next_button"
          android:drawableLeft="@drawable/arrow_righ
          android:drawablePadding="4dp"/>

*以@string/開頭的定義是引用字元串資源*

*以@drawable/開頭的定義是引用drawable資源*

ImageButton組件繼承自ImageView。Button組件則繼承自TextView。ImageView和TextView繼承自View

也可以ImageButton組件替換Button組件。刪除next按鈕的text以及drawable屬性定義,並添加ImageView屬性。

 <ImageButton
          android:id="@+id/next_button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:src="@drawable/arrow_right"
          android:contentDescription="@string/next_button"/>

6. activity的生命周期

設備旋轉時,系統會銷毀當前QuizActivity實例,然後創建一個新的QuizActivity實例。所以每次旋轉設備用戶每次都會從第一題開始,現在來修正這個缺陷。

  • 創建水平模式佈局

右鍵單擊res目錄選擇New->Android resource directory。資源類型選擇layout,保持Source set的main選項不變,選擇待選資源列表中的Orientation,然後單擊>>按鈕將其移動到已選資源特征區域。

最後,確認選中Screen orientation下拉列表中的Landscape選項,並確保目錄名顯示為layout-land

這裡的-land尾碼名是配置修飾符的另一個使用例子。Android依靠res子目錄的配置修飾符定位最佳資源以匹配當前設備配置。設備處於水平方向時,Android會找到並使用res/layout-land目錄下的佈局資源。其它情況下,它會預設使用res/layout目錄下的佈局資源。

  • 將res/layout目錄下的activity_quiz.xml文件複製到res/layout-land目錄。

註意:兩個佈局文件的文件名必須相同,這樣它們才能以同一個資源ID被引用

  • 水平模式佈局修改(layout-land/activity_quiz.xml)

FrameLayout替換了最上層的LinearLayout。FrameLayout是最簡單的ViewGroup組件,它一概不管如何安排其子視圖的位置。FrameLayout子視圖的位置排列取決於它們各自的android:layout_gravity屬性

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/question_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:padding="24dp" />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|center_horizontal"
        android:orientation="horizontal">

        <Button
            android:id="@+id/true_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/true_button"/>
        <Button
            android:id="@+id/false_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/false_button"/>
    </LinearLayout>
    <Button
        android:id="@+id/cheat_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center"
        android:text="@string/cheat_button"/>

    <Button
        android:id="@+id/pre_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|left"
        android:text="@string/pre_button"
        android:drawableLeft="@drawable/arrow_left"
        android:drawablePadding="4dp"/>
    <ImageButton
        android:id="@+id/next_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:src="@drawable/arrow_right"
        android:contentDescription="@string/next_button"/>
</FrameLayout>
  • 保存數據以應對設備旋轉

覆蓋以下Activity方法

protected void onSaveInstanceState(Bundle outState)
  • 該方法通常在onStop()方法之前由系統調用,除非用戶按後退鍵。
  • 該方法的預設實現要求所有activity視圖將自身數據狀態保存在Bundle對象中。Bundle是存儲字元串鍵與限定類型值之間映射關係(鍵值對)的一種結構。
public class QuizActivity extends AppCompatActivity {
    ......
    private int mCurrentIndex=0;
    private static final String KEY_INDEX="index";
    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
      
        savedInstanceState.putInt(KEY_INDEX,mCurrentIndex);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_quiz);
        
        if(savedInstanceState!=null){
            mCurrentIndex=savedInstanceState.getInt(KEY_INDEX,0);
        }
        ......
    }
    ......
}

7. 日誌

public static int d(String tag,String msg)//輸出日誌信息d:debug

方法的第一個參數通常是以類名為值的TAG常量傳入

public class QuizActivity extends AppCompatActivity {
    private static final String TAG="QuizActivity";
    ......
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        Log.d(TAG,"onCreate(Bundle) called");
        
        setContentView(R.layout.activity_quiz);
      
        ......
    }
}
日誌級別 方法 說明
ERROR Log.e(...) 錯誤
WARNING Log.w(...) 警告
INFO Log.i(...) 信息型消息
DEBUG Log.w(...) 調試輸出
VERBOSE Log.v(...) 僅用於開發

所有的日誌記錄方法都有兩種參數簽名:string類型的tag參數和msg參數;除tag和msg參數外再加上Throwable實例參數

9. 第二個activity

新activity將帶來第二個用戶界面,方便用戶偷看問題的答案

第二個activity的佈局組件的定義(activity_cheat.xml)

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context="com.example.mdx.studyworks.CheatActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp"
        android:text="@string/warning_text"/>
    <TextView
        android:id="@+id/answer_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp"
        tools:text="Answer"/>
    <Button
        android:id="@+id/show_answer_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/show_answer_button"/>

</LinearLayout>

activity_cheat.xml 效果圖

  • 註意用於顯示答案的TextView組件,它的tools和tools:text屬性的命名空間比較特別。該命名空間可以覆蓋某個組件的任何屬性。這樣,可在預覽中看到效果,而在運行時Answer文字不會顯現出來。
  • 應用的所有activity都必須在manifest配置文件中聲明,這樣操作系統才能找到它們。
//在manifest配置文件中聲明CheatActivity
<activity android:name=".CheatActivity">
        </activity>

啟動activity

public void startActivity(Intent intent)

activity調用startActivity(Intent)方法時,調用請求實際發給了操作系統的ActivityManager。ActivityManager負責創建Activity實例並調用其onCreate(Bundle)方法

public Intent(Context pageContext,Class<?> cls)

傳入該方法的Class類型參數告訴ActivityManager應該啟動哪個activity

Context參數告訴ActivityManager在哪裡可以找到它

    mCheatButton=(Button)findViewById(R.id.cheat_button);
    mCheatButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //從QuizActivity啟動CheatActivity
            Intent i=new Intent(QuizActivity.this,CheatActivity.class);
            startActivity(i);   
        }
    });

activity間數據傳遞

  • 使用 intent extra

將extra數據信息添加給intent,調用Intent.putExtra(...)方法

public Intent putExtra(String name,boolean value)
 Intent i=new Intent(QuizActivity.this,CheatActivity.class);
 i.putExtra(EXTRA_ANSWER_IS_TRUE,answerIsTrue);
 startActivity(i)

從extra獲取數據

public boolean getBooleanExtra(String name,boolean defaultValue)
 mAnswerIsTrue=getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE,false);

Activity.getIntent()方法返回了由startActivity(Intent)方法轉發的Intent對象

  • 從子activity獲取返回結果
//父activity
/*第二個參數是請求碼,*/
public void startActivityForResult(Intent intent,int requestCode)

//子activity發送返回信息給父activity,有2種方法
public final void setResult(int resultCode)
public final void setResult(int resultCode,Intent data)

resultCode可以是以下任意一個預定義常量

  • Activity.RESULT_OK ,即1
  • Activity.RESULT_CANCELED ,即0

如需自定義結果代碼,還可使用另一個常量:RESULT_FIRST_USER

//父,QuizActivity
 private static final int REQUEST_CODE_CHEAT=0;
 
 mCheatButton.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
            boolean answerIsTrue=mQuestionBank[mCurrentIndex].isAnswerTrue();
            
            Intent i=new Intent(QuizActivity.this,CheatActivity.class);
            i.putExtra(EXTRA_ANSWER_IS_TRUE,answerIsTrue);
            startActivityForResult(i,REQUEST_CODE_CHEAT);
        }
});
//處理返回結果
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //super.onActivityResult(requestCode, resultCode, data);
        //結果碼不一致
        if (resultCode!= Activity.RESULT_OK){
            return;
        }
        //結果碼一致
        if (requestCode==REQUEST_CODE_CHEAT){
            if (data==null){
                return;
            }
            //解析結果intent
            mIsCheater=data.getBooleanExtra(EXTRA_ANSWER_SHOW,false);
            
        }
    }
//子,CheatActivity
 Intent data=new Intent();
 data.putExtra(EXTRA_ANSWER_SHOW,isAnswerShown);
 setResult(RESULT_OK,data);//設置返回結果
 

10. activity的使用與管理

被指定為應用的第一個activity

<!--指定第一個activity是QuizActivity-->
<activity android:name=".QuizActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 博客園是個非常好的學習知識的地方,相信有很多人跟我一樣,園齡3年,從博客園不知道拷了多少代碼,看了多少博客,自己卻一篇博客都沒寫過。真是罪過。 這次準備寫幾篇關於這個項目源碼的閱讀和理解的文章,大家一起相互學習學習,我可能不會單單就寫源碼一類的東西,還會做很多擴展,比如新的c++的語法,其他的一些工 ...
  • 1 異常概述 2 異常體系 3 異常的原理 4 異常對象的拋出 5 自定義異常&異常類的拋出(throws) 6 異常的分類 7 throw和throws的區別? 8 異常的捕獲 9 異常處理的原則 10 異常的註意事項 ...
  • 簡介 網路無處不在,移動互聯時代也早已到來,單機版程式慢慢的已沒有生命力,所有的程式都要能夠訪問網路,比如 QQ 網路聊天程式、迅雷下載程式等,這些程式都要同網路打交道,本次將與各位小伙伴們分享的就是 Java 中的網路編程—— Socket 通信。 網路基礎知識 兩台電腦要通過網路進行通信,必須 ...
  • 一、添加 devtools 依賴 當配置了 devtools 後,我們在classpath修改任何文件項目都將會自動重啟。 (1)某些資源在更改時不一定需要觸發重新啟動。例如, Thymeleaf 模板可以就地進行編輯。預設情況下更改資源路徑包括了:/META-INF/maven, /META-IN ...
  • 最近做了幾道關於二分法的題目,覺得比較典型,因此拿出來說一說。 首先,先把題目分享一下。 題目描述:上題中講了一個故事,故事大意不用過多關註,有用部分為:某地主有一個大糧倉,這個糧倉容量為 n 個單位,但這個糧倉有個小口,每天會有一部分麻雀過來偷吃糧食,同時地主每天也會從別的地方運來糧食填補。開始的 ...
  • 我是一名建築學的學生,第一次瞭解到Python這門課是選課的時候。說實話,學c語言的時候我學的就並不好,感覺自己並沒有天分。我只是按照我的人才培養方案看課的時候才第一次看到這門課。起初並不知道這門課意味著什麼,就給軟工的朋友打電話咨詢。然後又上百度搜索,感覺還挺有用,就選了這門課。 一個建築生,平時 ...
  • 自己以前從來沒有寫博客的想法,但是學Python,裡面的老師也說了,寫博客可以加深自己的記憶,也能回顧內容。還能給別人參考。挺值的。2017-09-16 一、 Python介紹 python的創始人為吉多·範羅蘇姆(Guido van Rossum)。1989年的聖誕節期間,吉多·範羅蘇姆為了在阿姆 ...
  • 首先分析第一個比較重要的方法 put 方法,源碼如下 分析上面的源碼,我們可以得到下麵的結論: 當我們試圖將一個key-value 調用put方法放入HashMap的時候,首先會調用key的hashCode方法算出該Entry存放的位置,若兩個key的hashCode相同則在table中的存儲位置相 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...