資訊農夫
2019/05/10
2019/04/20
[java][kotlin] Thread 與 Runnable 的使用時機與說明
多執行緒 Thread 與 Runnable的使用一直以來不是很得要領
許多書上或網路上的說明都無法讓我完全理解
偶然的一篇文章,讓我豁然開朗,趕緊記錄下自己的理解與心得。
對java 與 kotlin來說要給其他執行續執行的程式必須單獨用一個class包裝起來
這句話的意思是,一定得是呼叫另一個class來執行多執行緒,而不是
在目前的class呼叫fun來執行多執行緒。
在這個認知的前提下,就可以很明確的區分Thread 與 Runnable的使用時機:
Thread:
Thread的用途是,class可以繼承Thread的時候也就是,請看程式碼:
java
public class test extends Thread
{
@Override
public void run()
{
super.run();
}
}
kotiln
public class ApiBase: Thread()
{
override fun run()
{
super.run()
}
}
以上要執行多執行緒的程式全都寫到 run的方法裡,使用時只需要呼叫 .start()方法就好
Runnable:
Runnable的用途是,當class無法繼承Thread的時候,也就是class已經繼承了其他類別
請看程式碼:
java
public class test implements Runnable
{
@Override
public void run()
{
super.run();
}
}
kotiln
public class ApiBase: Runnable
{
override fun run()
{
TODO("not implemented")
}
}
以上要執行多執行緒的程式除了都寫到 run的方法裡之外,在使用上還要特別注意的是
Runnable 畢竟只是一個介面,所以在使用上
還是必須掀起動一個Thread,再把Runnable丟入執行。
請看範例:
java
public class test implements Runnable
{
@Override
public void run()
{
super.run();
}
}
public class test2
{
test ts1 = new test();
Thread thr = new Thread(ts1);
thr.start();
}
kotiln
public class ApiBase: Runnable
{
override fun run()
{
TODO("not implemented")
}
}
public class test2
{
val ts1: test = test()
val thr: Thread = Thread(ts1)
thr.start()
}
2019/04/16
[macOS] vim 常用命令
終端機理要編輯檔案時,vim是非常好用的工具,這裡紀錄常用的命令避免忘記
vim 命令分成兩種:鍵盤命令鍵、命令列指令
vim的啟動方式:
vim
啟動vim編輯器,同時顯示空白的新編輯畫面
vim 檔案名稱
啟動vim編輯器,並開啟指定的檔案
鍵盤命令鍵:
i 進入編輯模式,編輯模式下才可以修改檔案的內容
esc 取消指令或退出編輯模式
命令列指令:
:w
存檔
:w 新檔案名稱
另存新檔
:q
不存檔直接退出vim
:wq
存檔後退出vim
[Android Studio 3] adb 常用命令
這裡單純紀錄曾經使用過的命令,避免忘記
使用adb在手機外部超作(未shell進手機)
adb shell 登入目前唯一連接的手機
adb devices 查詢目前有連接的手機
adb pull /手機目錄位置/檔案名稱 /電腦目錄位置/ 把手機的檔案複製到電腦上
這個功能用最多的地方是在檢查sqlite的檔案,sqlite檔案位置:
/data/data/專案名稱/databases/sqlite file
檔案位置範例:/data/data/com.test.test1/databases/Data1.db3
完整命令範例:adb pull /data/data/com.test.test1/databases/Data1.db3 /Users/use/
手機內部操作(已shell進手機)
cd 目錄名稱 切換目錄
ls 顯示目前所在目錄的所有資料
exit 離開手機
2019/04/15
[Android Studio 3] ADB 登入emulator 模擬器 取得 ROOT權限
第一步
這是最重要的一步,建立模擬機時必須選擇不支援Play Stone的系統
這個就不支援play stone可以放心的使用
這個有支援play stone是沒辦法取得root權限的
第二步
模擬機開啟開發人員模式,並開啟USB偵錯
第三步
使用adb工具輸入命令開啟root權限
adb工具不必連線進入模擬器,只要確保當下只有模擬器啟動,沒有其他真實手機接入電腦就可以了
開啟root命令
先輸入 adb root
如果回傳 restarting adbd as root 代表成功
接者輸入 adb remount
就可以取得root權限登入模擬機了
2018/01/11
[C#] DateGridView 使用 ComboBox 與 DateTimePicker
這一篇主要是針對 https://nonfu.blogspot.tw/2017/12/c-dategridview-datetimepicker.html 所併發出來的想法與程式碼改進 主要就是讓 DataGridView 能使用 DateTimePicker 與 ComboBox 並改進不足之處。
2017/12/17
[C#] DateGridView 使用 DateTimePicker 輸入日期
使用DateGridView常常遇到需要輸入日期的情境,對使用者來說DateTimePicker是很直覺的輸入方式
但是原始的DateGridView並不支援DateTimePicker的使用,以往為了解決這個問題,我都是參考微軟
的這一篇 https://msdn.microsoft.com/zh-tw/library/7tas5c80.aspx 進行修改
最近看到這一篇 https://dotblogs.com.tw/danking/2014/11/13/147294 讓我興起改寫
DateGridView的想法。
對於改寫控制項還不是很了解要如何使用在專案的人,可以參考我的另一篇文https://nonfu.blogspot.tw/2017/11/c-checkbox.html
public partial class DataGridViewEx:System.Windows.Forms.DataGridView
{
// 紀錄可編輯的欄位名稱
private StringDictionary ColmmEdit;
// 紀錄要使用日期資料的欄位名稱
private StringDictionary ColmmDate;
public DataGridViewEx() : base()
{
this.EditMode = DataGridViewEditMode.EditProgrammatically;
if (!DesignMode)
{
ColmmEdit = new StringDictionary();
ColmmDate = new StringDictionary();
this.Disposed += DataGridViewEx_Disposed;
this.CellClick += DataGridViewEx_CellClick;
this.EditingControlShowing += DataGridViewEx_EditingControlShowing;
}
}
// 刪除資料清單
private void DataGridViewEx_Disposed(object sender, EventArgs e)
{
if (!DesignMode)
{
ColmmEdit.Clear();
ColmmDate.Clear();
}
}
// 設定可編輯的欄位
public void SetColmmEditName(string NameValue)
{
if(!ColmmEdit.ContainsKey(NameValue))
{
ColmmEdit.Add(NameValue, NameValue);
}
}
// 設定要使用DateTimePicker的欄位
public void SetColmmDateName(string NameValue)
{
if (!ColmmDate.ContainsKey(NameValue))
{
ColmmDate.Add(NameValue, NameValue);
}
}
// 檢查欄位是否可以編輯
private void DataGridViewEx_CellClick(object sender, DataGridViewCellEventArgs e)
{
if ((e.RowIndex > -1) || (e.ColumnIndex > -1))
{
if (ColmmEdit.ContainsKey(this.Columns[e.ColumnIndex].Name))
{
this.BeginEdit(true);
}
else
{
this.EndEdit();
}
}
}
// DateTimePicker的日期資料回寫欄位
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
this .CurrentCell.Value = ((DateTimePicker)sender).Value.ToString("yyyy/MM/dd");
}
// 判斷是否適用DateTimePicker的欄位
private void DataGridViewEx_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (this.CurrentCell.ColumnIndex > -1)
{
Control parentCTL = e.Control.Parent;
if(ColmmDate.ContainsKey(this.Columns[this.CurrentCell.ColumnIndex].Name))
{
DateTimePicker dtPicker = new DateTimePicker();
dtPicker.Name = "dateTimePicker1";
dtPicker.Size = this .CurrentCell.Size;
dtPicker.Format = DateTimePickerFormat.Custom;
dtPicker.CustomFormat = "yyyy/MM/dd";
dtPicker.Location = new Point(
e.Control.Location.X - e.Control.Margin.Left < 0 ? 0 : e.Control.Location.X - e.Control.Margin.Left,
e.Control.Location.Y - e.Control.Margin.Top < 0 ? 0 : e.Control.Location.Y - e.Control.Margin.Top);
if (e.Control.Text != "")
{
dtPicker.Value = DateTime.ParseExact(e.Control.Text, dtPicker.CustomFormat, null);
}
else
{
dtPicker.Value = DateTime.Now;
this.CurrentCell.Value = dtPicker.Value.ToString("yyyy/MM/dd");
}
e.Control.Visible = false;
foreach (Control tmpCTL in parentCTL.Controls)
{
if (tmpCTL.Name == dtPicker.Name) parentCTL.Controls.Remove(tmpCTL);
}
parentCTL.Controls.Add(dtPicker);
dtPicker.ValueChanged += new EventHandler(dateTimePicker1_ValueChanged);
}
else
{
foreach (Control tmpCTL in parentCTL.Controls)
{
if (tmpCTL.Name == "dateTimePicker1")
{
parentCTL.Controls.Remove(tmpCTL);
}
}
}
}
}
}
訂閱:
文章 (Atom)