1. 程式人生 > >20189230楊靜怡 2018-2019-2 《移動平臺開發實踐》第6周學習總結

20189230楊靜怡 2018-2019-2 《移動平臺開發實踐》第6周學習總結

cast insert 管理 next 無法 fec boolean update 博客

目錄

  • 學習《Java和Android開發學習指南(第二版)》第23、24、25、26章——
  • 教材學習中的問題和解決過程
  • 代碼調試中的問題和解決過程
  • 上周錯題總結
  • [代碼托管]
  • statistics.sh腳本運行結果的截圖
  • 學習進度條
  • 參考資料

學習《Java和Android開發學習指南(第二版)》第23、24、25、26章——

第23章 Android簡介
1.Android向後兼容,針對較早的版本編寫的應用程序,總能夠在新的版本上運行。

2.4種Android應用程序組件:
?活動(Activity):包含用戶交互組件的一個窗口。
?服務(Service):在後臺長時間運行的操作。
?廣播接收者(Broadcast receiver):一個監聽器,負責對系統或應用程序聲明作出響應。
?內容提供者(Content provider):管理要和其他應用程序分享的一組數據的一個組件。
3.每個應用程序都必須有一個清單(manifest),描述該應用程序。清單以XML文件的形式給出,其中包含的內容有:
?運行該應用程序所需的最小API Level。
?應用程序的名稱。這個名稱將會顯示在設備上。
?當用戶在其手機或平板電腦的主屏幕上觸碰該應用程序的圖標時,將會打開的第一個活動(窗口)。
?是否允許從其他的應用程序調用你的應用程序組件。
?對於在目標設備上安裝的應用程序,用戶必須保證一組什麽樣的許可。如果用戶不能保證所有必須的許可,將不會安裝該應用程序。

第24章 初識Android
24.4 應用程序結構
1.Project窗口中有兩個主要的節點,app和Gradle Scripts。App節點包含了應用程序中所有的組件。Gradle Scripts節點包含了Gradle構件腳本,供Android Studio構建你的項目。
app節點下面有如下的3個節點:
?Manifests。包含了一個AndroidManifest.xml文件,它描述了應用程序。
?java。包含了所有的Java應用程序和測試類。

?res。包含了資源文件。在這個目錄下還有一些目錄:
drawable(包含了用於各種屏幕分辨率的圖像),layout(包含了布局文件)和menu(包含了菜單文件),mipmap(包含了用於各種屏幕分辨率的app圖標),還有values(包含了字符串和其他值)。
2.R類
R類是一個名為R的通用的Java類,可以在項目的app/build/generated/source目錄下找到。R包含了嵌套的類,該類反過來包含了所有資源ID。每次添加、修改或刪除資源的時候,都會重新生成R。例如,如果你向res/drawable目錄添加了一個名為logo.png的文件,Android Studio將在drawable類下面生成一個名為logo的文件。R的作用是讓你能夠引用代碼中的一個資源。
24.4.1 Android清單
1.創建一個新項目241
(1)主函數

package com.example.yangxiaopang.a241;

        import android.support.v7.app.AppCompatActivity;
        import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

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

(2)清單文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

(3)項目運行結果
打印出Hello World!
技術分享圖片

第25章活動
25.1 活動的生命周期
技術分享圖片

25.2 ActivityDemo示例
1.代碼清單25.1 ActivityDemo的清單

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.activitydemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

2.代碼清單25.2 ActivityDemo的MainActivity類

package com.example.activitydemo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("lifecycle", "onCreate");
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d("lifecycle", "onStart");
    }

    @Override
    public void onRestart() {
        super.onRestart();
        Log.d("lifecycle", "onRestart");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d("lifecycle", "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d("lifecycle", "onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d("lifecycle", "onStop");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("lifecycle", "onDestroy");
    }
}

技術分享圖片
技術分享圖片

25.5 啟動另一個活動
1.代碼清單25.3 SecondActivityDemo的清單

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.secondactivitydemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.secondactivitydemo.SecondActivity"
            android:label="@string/title_activity_second" >
        </activity>
    </application>

</manifest>

2.代碼清單25.4 activity_main.xml文件

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/first_screen" />

</RelativeLayout>

3.代碼清單25.5 activity_second.xml文件

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".SecondActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

4.代碼清單25.6 MainActivity類

package com.example.secondactivitydemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.TextView;

public class MainActivity extends Activity implements
        OnTouchListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = (TextView) findViewById(R.id.textView1);
        tv.setOnTouchListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it 
        // is present. 
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onTouch(View arg0, MotionEvent event) {
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra("message", "Message from First Screen");
        startActivity(intent);
        return true;
    }
}

5.代碼清單25.7 SecondActivity類

package com.example.secondactivitydemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.widget.TextView;

public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Intent intent = getIntent();
        String message = intent.getStringExtra("message");
        ((TextView) findViewById(R.id.textView1)).setText(message);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_second, menu);
        return true;
    }
}

技術分享圖片技術分享圖片

第26章UI組件
26.1 概覽
1.微件和布局,都在android.view.View類中實現。
26.2 使用Android Studio UI工具
1.使用UI工具所做的事情,都會反映到布局文件中,以XML元素的形式體現出來。要查看你生成了什麽,單擊UI工具底部的XML視圖即可。
26.3 使用基本組件
1.代碼清單26.1 BasicComponents項目的清單文件

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

   <!--uses-sdk android:targetSdkVersion="17" /-->

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.basiccomponents.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category
                    android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest> 

2.代碼清單26.2 res/values下的strings.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">BasicComponents</string>
    <string name="action_settings">Settings</string>
    <string name="prompt_email">Email</string>
    <string name="prompt_password">Password</string>
    <string name="action_sign_in"><b>Sign in</b></string>
</resources>

3.代碼清單26.3 布局文件

<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:layout_gravity="center"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:padding="120dp"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/prompt_email"
        android:inputType="textEmailAddress"
        android:maxLines="1"
        android:singleLine="true" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/prompt_password"
        android:imeActionId="@+id/login"
        android:imeOptions="actionUnspecified"
        android:inputType="textPassword"
        android:maxLines="1"
        android:singleLine="true" />

    <Button
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginTop="16dp"
        android:paddingLeft="32dp"
        android:paddingRight="32dp"
        android:text="@string/action_sign_in" />

</LinearLayout>

4.代碼清單26.4 BasicComponents項目的MainActivity類

package com.example.basiccomponents;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;

public class MainActivity extends Activity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it 
        // is present. 
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
}

技術分享圖片

26.5 通知
1.代碼清單26.5 NotificationDemo的主活動的布局文件

<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:layout_gravity="center"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:padding="120dp"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/prompt_email"
        android:inputType="textEmailAddress"
        android:maxLines="1"
        android:singleLine="true" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/prompt_password"
        android:imeActionId="@+id/login"
        android:imeOptions="actionUnspecified"
        android:inputType="textPassword"
        android:maxLines="1"
        android:singleLine="true" />

    <Button
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginTop="16dp"
        android:paddingLeft="32dp"
        android:paddingRight="32dp"
        android:text="@string/action_sign_in" />

</LinearLayout>

2.代碼清單26.6 主活動類

package com.example.notificationdemo;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {
    int notificationId = 1001;

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    public void setNotification(View view) {
        Intent intent = new Intent(this, SecondActivity.class);
        PendingIntent pendingIntent =
                PendingIntent.getActivity(this, 0, intent, 0);

        Notification notification  = new Notification.Builder(this)
                .setContentTitle("New notification")
                .setContentText("You've got a notification!")
                .setSmallIcon(android.R.drawable.star_on)
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                .addAction(android.R.drawable.ic_menu_gallery,
                        "Open", pendingIntent)
                .build();
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(
                        NOTIFICATION_SERVICE);
        notificationManager.notify(notificationId, notification);
    }

    public void clearNotification(View view) {
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(
                        NOTIFICATION_SERVICE);
        notificationManager.cancel(notificationId);
    }
}

技術分享圖片

單擊Set Notification按鈕,通知圖標(一個橙色的星)將會出現在狀態欄上:
技術分享圖片

將狀態欄向屏幕的右下方拖動以打開通知繪制區:
技術分享圖片

觸碰通知啟動SecondActivity:
技術分享圖片

教材學習中的問題和解決過程

  • 問題1:本周出現的問題主要是Android Studio下載安裝和使用的問題。
  • 問題解決方案1:把Android Studio項目從C盤移植到了D盤,解決了SDK包和模擬器所占內存空間太大,導致項目無法運行的問題。

代碼調試中的問題和解決過程

  • 問題1:從配套程序示例中直接導入的項目多次報錯,無法運行。
  • 問題1解決方案:
    (1)Error:Unsupported method: BaseConfig.getApplicationIdSuffix().
    A.修改項目的build.gradle文件,找到dependencies,修改classpath
    classpath ‘com.android.tools.build:gradle:1.0.0‘
    改成:
    classpath ‘com.android.tools.build:gradle:3.2.0‘;
    B.上一步修改了build.gradle中的版本之後,gradle-wrapper.properties文件中的gradle的版本也需要修改,
    直接修改:distributionUrl
    distributionUrl=https://services.gradle.org/distributions/gradle-4.6-all.zip
    (2)修改後運行又報錯:
    Configuration ‘compile’ is obsolete and has been replaced with ‘implementation’ and ‘api’.
    It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html
    A.修改build gradle:compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])為implementation fileTree(dir: ‘libs‘, include: [‘*.jar‘])即可。
  • 問題2:本周課堂作業在上傳碼雲的時候總是push報錯
  • 問題2解決方案:在app處git bash here上傳src文件夾的時候,如不手動更改src文件夾名稱,就會在pull和push過程中將先前的項目自動覆蓋。

上周錯題總結

1.Assume that you have an InputStream whose next bytes are XYZABC. What is the result of
calling the following method on the stream, using a count value of 3?
假如有一個InputStream,接下來的內容是XYZABC,下面代碼中假如count
為3,下面代碼執行結果是?
public static String pullBytes(InputStream is, int count) throws IOException
{
is.mark(count);
final StringBuilder sb = new StringBuilder();
for(int i=0; i<count; i++)
sb.append((char)is.read());
is.reset();
is.skip(1);
sb.append((char)is.read());
return sb.toString();
}
A .It will return a String value of XYZ.
B .It will return a String value of XYZA.
C .It will return a String value of XYZX.
D .It will return a String value of XYZB.
E .It will return a String value of XYZY.
F .The code does not compile.
G .The code compiles but throws an exception at runtime.
H .The result cannot be determined with the information given.
正確答案: H 我的答案: A
並非所有java.io流都支持mark()操作;因此,如果不在流上調用mark-supported(),則在運行時之前結果是未知的。如果流確實支持mark()操作,那麽結果將是xyzy,因為reset()操作將流放回調用mark()之前的位置,skip(1)將跳過x,e將正確。如果流不支持mark()操作,則可能會引發運行時異常,並且g是正確的。因為不知道輸入流是否支持mark()操作,所以h是唯一正確的選擇。

2.What is the value of name after an instance of Eagle is serialized and then deserialized?
Eagle的一個實例經過serialized 和 deserialized後,name的值是?
public class Bird implements Serializable {
protected transient String name = "Bridget";
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public Bird() {
this.name = "Matt";
}
}
public class Eagle extends Bird implements Serializable {
{ this.name = "Janette"; }
public Eagle() {
this.name = "Daniel";
}
}
A .Bridget
B .Matt
C .Janette
D .Daniel
E .null
F .The code does not compile.
G .The code compiles but throws an exception at runtime.
H .The value may not be known until runtime.
正確答案: E 我的答案: B
首先,雖然bird類實現了serializable,但它沒有定義建議但不需要的非靜態serial version uid變量;因此它編譯時沒有問題,而f是不正確的。代碼也可以毫無問題地運行,因此g是不正確的。這裏的關鍵是,Java將在反序列化期間調用第一個非序列化的無參數父類的構造函數,跳過任何構造函數和介於其間的序列化類的默認初始化,包括EGLE和BED本身。因此,object()是第一個被調用的構造函數。跳過所有默認初始化,因此a、b、c和d都不正確。由於名稱被標記為瞬態,因此反序列化的值為空,並且e是正確的。h也不正確,因為調用方不能用setname()更改name的序列化值,因為name被標記為transien。

3.Assuming the following class has proper public getter/setter methods for all of its private fields, which of the following fields will always be null after an instance of the class is
serialized and then deserialized? (Choose all that apply.)
加入下面的類的private成員都有合適的public getter/setter,類的實例serialized and 和 deserialized後哪些成員會是null?
public class Zebra implements Serializable {
private static final long serialUID = 1L;
private transient String name = "George";
private static String birthPlace = "Africa";
private transient Integer age;
private java.util.List friends = new java.util.ArrayList<>();
private Object tail = null;
{ age = 10;}
public Zebra() {
this.name = "Sophia";}
}
}
A .name
B .tail
C .age
D .friends
E .birthPlace
F .The code does not compile.
G .The code compiles but throws an exception at runtime.
正確答案: A C 我的答案: B D
代碼編譯和運行時沒有問題,因此f和g是不正確的。請註意,serial uid與serial version uid不同,盡管建議使用serial version uid,但不需要使用,因此不會造成任何編譯問題。請註意,序列化過程不會使用seria luid進行版本控制。名稱變量和年齡變量都是暫時的,這意味著它們的值在序列化時不會被保存。反序列化後,將跳過默認初始化和構造函數,它們都將為空;因此a和c是正確的。B不正確,因為它不是暫時的,並且可以由調用方在序列化之前設置。d也不正確,因為序列化的空數組與空指針不同。即使這些非瞬態字段可以設置為空,但在反序列化後它們也不能保證為空。E不正確,因為靜態值不會被序列化;反序列化後,它將在類上可用。

5.Which values when inserted into the blank would allow the code to compile? (Choose all
that apply.)
插入哪些代碼可以讓下面的代碼正確編譯?
1: Console console = System.console();
2: String color = console.readLine("What is your favorite color? ");
3: console._("Your favorite color is "+color);
A .print
B .printf
C .println
D .format
E .writer().println
F .out
正確答案: B D E 我的答案: A C E
控制臺定義兩個輸出方法,format()和printf(),它們是相同的在函數中,所以b和d是正確的。a、c和f都不正確,因為在控制臺類中沒有定義具有該名稱的此類方法。還可以使用writer()方法訪問控制臺的printwriter對象,因此e是正確的。
11.Suppose that the file c:\book\java exists. Which of the following lines of code creates an
object that represents the file? (Choose all that apply.)
A .new File("c:\book\java");
B .new File("c:\book\java");
C .new File("c:/book/java");
D .new File("c://book//java");
E .None of the above
正確答案: B C 我的答案: A C
選項B是正確的,因為Java需要用另一個反斜杠來轉義反斜杠。選項C也是正確的,因為Java將在使用路徑時將斜杠轉換為右斜杠。
21.如果有以下代碼片段:
...
public
_________ void add(Object o) {
if(next == list.length) {
list = Arrays.copyOf(list, list.length * 2);
}
list[next++] = o;
}
...
為了確保add()在多線程訪問下的線程安全,應該加上()關鍵字。
A .abstract
B .synchronized
C .static
D .volatile
正確答案: B 我的答案: D
要點:synchronized和volatile的使用方法以及區別——
一旦一個共享變量(類的成員變量、類的靜態成員變量)被volatile修飾之後,那麽就具備了兩層語義:
1)保證了不同線程對這個變量進行操作時的可見性,即一個線程修改了某個變量的值,這新值對其他線程來說是
立即可見的。
2)禁止進行指令重排序。
volatile本質是在告訴jvm當前變量在寄存器(工作內存)中的值是不確定的,需要從主存中讀取;
synchronized則是鎖定當前變量,只有當前線程可以訪問該變量,其他線程被阻塞住。
1.volatile僅能使用在變量級別;
synchronized則可以使用在變量、方法、和類級別的
2.volatile僅能實現變量的修改可見性,並不能保證原子性;
synchronized則可以保證變量的修改可見性和原子性
3.volatile不會造成線程的阻塞;
synchronized可能會造成線程的阻塞。
4.volatile標記的變量不會被編譯器優化;
synchronized標記的變量可以被編譯器優化

[代碼托管]

https://gitee.com/EvelynYang/sixth_week_homework

statistics.sh腳本運行結果的截圖

新建AndroidProjects文件夾運行腳本,之前都是在IdeaProjects文件夾裏運行。
技術分享圖片

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一周 200/200 2/2 20/20
第二周 300/500 1/3 18/38
第三周 500/1000 1/4 38/76
第四周 1000/2000 1/5 20/96
第五周 1000/3000 1/6 25/121
第六周 1000/4000 1/7 25/146

參考資料

  • 《Java和Android開發學習指南(第二版)(Java for Android.2nd)》
    -[Android Studio中文社區](http://www.android-studio.org/)

20189230楊靜怡 2018-2019-2 《移動平臺開發實踐》第6周學習總結