Android第一行程式碼踩坑qwq

2020-08-13 13:23:44

涉及到需要更新或者更換的方法

結合在網上部分填坑操作上進行總結跟改寫

圖片的最優輸出方式


	setImageResource(int id);最常用的圖片輸出方式,但容易因爲UI耗時而引起程式崩潰.....

	setImageBitmap()就是把Bitmap物件封裝成Drawable物件,更會頻繁呼叫該物件

	所以建議更改成爲:imageView.setImageDrawable(getResources().getDrawable(int id));

	但是API>19方法會顯示過時,這是由於getDrawable(int id,Theme theme)需要第二個參數,可以直接傳null
	或者Context.getDrawable(int)

	綜上,setImageDrawable()是最省記憶體高效的,當然如果擔心圖片過大或者圖片過多影響記憶體和載入效率,可以自己解析圖片然後通過呼叫setImageDrawable方法進行設定。

博主自用功能快捷鍵

Ctrl+R 替換文字

Ctrl+N 可以快速開啓類

Ctrl+Q 把遊標移至方法處,按此組合鍵可快速檢視方法的說明文件。

Ctrl+E 快速檢視最近開啓開啓過的檔案

Alt+F1 查詢程式碼所在位置

Ctrl+D 集合了複製和貼上兩個操作, 如果有選中的部分就複製選中的部分,並在選中部分的後面

shift+F6 可對類、方法、變數進行重新命名,使用的地方會自動更新名字。

Alt+Enter 自動修正

Ctrl+空格 輸入程式碼時按此組合鍵會列出與之相匹配的類、方法名、成員變數等,起智慧提示的作用。

Ctrl+斜槓 註釋或取消註釋當前行或選中的程式碼塊

Ctrl+Alt+T 選中一塊程式碼,按此組合鍵,可快速新增if 、for、try/catch等語句。

Ctrl+Alt+L 格式化程式碼

Ctrl+Alt+V 呼叫方法時傳入的參數是比較複雜的表達式時,可用此組合鍵重構變數,以簡化程式碼的複雜度。

Alt+shift+C 檢視工程的最近修改。

Ctrl+滑鼠左鍵直接跳轉到類、方法、成員變數定義的地方

Ctrl+shift+I 快速檢視方法體,想檢視一個方法是如何實現的,可把遊標移至方法處,按此組合鍵

Ctrl+shift+A 快速查詢android studio中的選單

Alt+ Up/Down 程式碼向上/下移動

Ctrl+Alt+Space 類名或介面名提示

Ctrl+shift+斜槓 註釋或取消註釋選中的程式碼塊,以「/……/」方式註釋。

Ctrl+shift+Enter 自動匹配相對應的語法結構,比如if,do-while,try-catch等結構。

Ctrl+Alt+shift+N 快速開啓輸入的方法或變數。

Ctrl+Shift+Space 自動補全程式碼

Ctrl+Shift+Up/Dow在方法間快速移動定位

Ctrl+Alt+shift+I 檢測程式碼,比如檢測一些定義了,但沒有使用過的變數或方法。檢測的目的是爲了提高程式碼效率。

RecyclerView的點選事件

見Android第一行程式碼P131,鑑於文中作者只給出的內部點選事件實現方式,博主在此給出介面回撥這種方法:
(1)定義介面

    public static interface OnItemClickListener {
        void onItemClick(int position);
        void onItemLongClick(int position);
    }

(2)宣告變數

    private OnItemClickListener mOnItemClickListener = null;

(3)選中變數後,Ctrl+O得到其的set()方法

    public void setmOnItemClickListener(OnItemClickListener mOnItemClickListener) {
        this.mOnItemClickListener = mOnItemClickListener;
    }

(4)在viewHolder註冊點選事件

(5)適配器呼叫

(6)進階:例如列舉物件進行View的辨別

    public static interface OnItemClickListener {
        void onItemClick(ViewName VIEW,int position);
    }
    ....
        public enum ViewName{
        ITEM,
        HEADER
    }

碎片替換方法的簡單封裝

/*
* manager 訊息 使用方法:getSupportFragmentManager() [activity] getActivity()[fragment]
* id frameLayout控制元件id 使用方法:R.id.frameLayout
* fragment 碎片類 使用方法:new fragment();
* */
public class FragmentUtils {

    public static void ReplaceFragment(FragmentManager manager, int id, Fragment fragment) {
        manager.beginTransaction()
                .replace(id, fragment)
                .addToBackStack(null)
                //跟commit()方法的區別是允許狀態值丟失
                .commitAllowingStateLoss();
    }
}

動態註冊廣播監聽網路變化方法過時的改寫

改寫前:見第一行程式碼P173

過時原因:發現NetworkInfo在API level 29中過時,ConnectivityManager中有許多返回值爲NetworkInfo的方法,自此一併不推薦使用。

    class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isAvailable()) {
                Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show();
            }
        }
    }

改寫後:

    class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            assert connectivityManager != null;
            NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
            if (networkCapabilities!=null){
                Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show();
            }
        }
    }

標準廣播

Android8.0後,廣播發送、接受更加嚴格,需要加入Component參數,intent.setComponent(new ComponentName(「包名」,「接收器類」));自定義動態廣播無需實現;

        Intent intent = new Intent("com.example.testapplication.MY_BROADCAST");
        intent.setComponent(new ComponentName("com.example.testapplication",
                "com.example.testapplication.receiver.MyBroadcastReceiver"));
        sendBroadcast(intent,null);

利用Git上傳程式碼至GitHub

利用Git提交原生代碼見P195,成功現實後:

	//git與github建立遠端連線
	git remote add origin git@github.com:dustdawn/test.git[ 自己的倉庫名 ]
	//push到遠端伺服器github
	git push -u origin master
	//Android實現更新
	![ 做出更新 ](https://img-blog.csdnimg.cn/20200813115856749.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hkcm9zYXk=,size_16,color_FFFFFF,t_70#pic_center)
	![ 提交更新事務 ](https://img-blog.csdnimg.cn/20200813115952649.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0hkcm9zYXk=,size_16,color_FFFFFF,t_70#pic_center)

通知的基本使用方法

更改前:

	Notification notification=new NotificationCompat.Builder(this)
                        .setContentText("")
                        .build();

原因是升級到Android O 版本後,NotificationCompat.Builder()該方法被以下方法取代:

	PendingIntent intent = PendingIntent.getActivity(MainActivity2.this, 0, new Intent(MainActivity2.this, MainActivity3.class), 0);
	NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
	assert manager != null;
	if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {  //Android O (8.0)以上版本需要渠道
	NotificationChannel notificationChannel = new NotificationChannel("1", "xxx",NotificationManager.IMPORTANCE_HIGH);//通知重要度,DEFAULT及以上,通知時手機預設會有振動
	manager.createNotificationChannel(notificationChannel);
	}
	NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity2.this, "1")
		.setContentTitle("This is content title")
		.setContentText("This is content title")
		.setWhen(System.currentTimeMillis())
		//需要內容全顯示
		//.setStyle(newNotificationCompat.BigTextStyle().bigText("DASSSSSSSSSSSSSSSSSSSSSSSSSSS"+"SDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"+"DSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +"DSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +"SDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADSDA"))
		.setVibrate(new long[]{0,1000,1000,1000})//震動
		.setLights(Color.RED,1000,1000)//LED燈
		//.setPriority(NotificationCompat.PRIORITY_MAX)//重要通知
		//.setDefaults(NotificationCompat.DEFAULT_ALL)//所以 預設設定
		.setSmallIcon(R.mipmap.ic_launcher)
		.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
		.setContentIntent(intent)
		.setAutoCancel(true);
		manager.notify(1, builder.build());

讀寫檔案

API 29中棄用getExternalStorageDirectory後如何來讀寫檔案?

	String file=Objects.requireNonNull(Content.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)).getPath();

百度地圖開發中的坑

(1).SHA1的獲取,建議直接使用下面 下麪給出的幫助類去列印,因爲用命令列獲取到自動生成的SHA1很大機率與程式自身的SHA1不符(博主有被坑到…qwq)

   public static String sha1(Context context) {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), PackageManager.GET_SIGNATURES);
            byte[] cert = info.signatures[0].toByteArray();
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] publicKey = md.digest(cert);
            StringBuilder hexString = new StringBuilder();
            for (byte b : publicKey) {
                String appendString = Integer.toHexString(0xFF & b)
                        .toUpperCase(Locale.US);
                if (appendString.length() == 1) {
                    hexString.append("0");
                }
                hexString.append(appendString);
                hexString.append(":");
            }
            String result = hexString.toString();
            return result.substring(0, result.length() - 1);
        } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

(2)讓地圖顯示,SDK初始化一定要放在檢視系結的前面

        SDKInitializer.initialize(this);
        //必須放在setContentView方法前
        setContentView(R.layout.activity_main);

否則報錯: you have not supplyed the global app context info from SDKInitializer.initialize(Context) function.

(3)儘量用真機偵錯

(4)建MarkerOption,用於在地圖上新增Marker的話,圖示大小一定要合適

Material Design

有基礎可以,直接建立專案進行更改

 Material Design的创建

Android繼續進階

(1)獲取全域性的Content,如剛剛的SDK初始化可以放在裏面

class MyApplication extends Application {
	
	private static Context mContext;
	
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        //SDK初始化
        SDKInitializer.initialize(this);
        //litepal初始化
        Litepal.initialize(this);
    }
}

(2)關於設定Java 8,現只需加入compileOptions設定,即可用Lambda表達式

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
    	......
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

(3)複述下自定義介面

1.構建介面

public
class ToastMylistener {
    ToastListener toastListener=null;

    public void setToastListener(ToastListener toastListener) {
        this.toastListener = toastListener;
    }

    public interface ToastListener {
        void showToast();
    }
}

2.實現介面

	implements ToastMylistener.ToastListener

3.呼叫方法

	    textView.setOnClickListener((view -> {
            showToast();
        }));

總結

第一行程式碼,真的是非常實用的工具書( 膜拜郭霖大佬 +。+),博主本來是也想着把前段時間出版不久的第一行程式碼第三版,學習到的開發經驗一起分享出來,奈何最近進度不佳,哈哈哈,不過後續會發布出來希望大家多多支援、指正呀!

此文原創、未經允許、不可轉載!!!

博主QQ:691828516 學生黨12小時 線上+。+

微信:IU_lost_child 你沒看錯 博主喜歡的是iu!!!

再次感謝大家的賞析!!!