JavaとC#の違い
自分はメインでC#を使っているのですが、とある理由でJavaもやらないといけなくなったのでまず両者の違いを知る意味も含めて簡単にまとめてみます。(適切ではないかもしれない)
C#とは
オブジェクト指向言語で、マイクロソフトの提唱する.NET Frameworkという実行環境での実行を前提とする。
メモリ管理
.NET Frameworkは自動メモリ管理で、ガベージコレクション(GC)が使われているためメモリを明示的に開放する処理が必要ない。
Javaも同様である。(C++は手動でメモリ管理する必要あり)
これは仮想実行環境(VES)で提供される。
C# | Java | |
---|---|---|
実行環境 | .Net Frameworkなど | JRE(Java Runtime Environment) |
仮想実行システム | CLR(共通言語ランタイム) | JVM(Java Virtual Machine) |
共通中間言語 | CIL | バイトコード |
アクセス修飾子
修飾子 | Java | C# |
---|---|---|
protected | 同一のパッケージ、または派生したクラスからアクセスが可能 | 派生したクラスからアクセスが可能 |
internal | 存在しない | 同一のアセンブリ(DLL)内でアクセスが可能 |
(default) | 同一のパッケージ内でアクセスが可能 | 同じクラス内からのみアクセスが可能(private) |
データ構造
変数 | C | C++ | Java |
---|---|---|---|
char | 1byte | 1byte | 2byte |
short | 2byte | 2byte | 2byte |
int | 2byte | 4byte | 4byte |
long | 4byte | 4byte | 8byte |
float | 4byte | 4byte | 4byte |
double | 8byte | 8byte | 8byte |
型 | データを保持する場所 |
---|---|
値型 | スタック上 |
参照型 | ヒープ上 |
基本構文
メインの書き方が微妙に異なる。
C#:
static void main(string[] args)
c++:
int main (int argc, char* argv[])
java:
public static void main(String[] args)
名前空間
C++: namespace
C#: namespace(.をつけて階層化可)
Java: パッケージ(ソースコードを置いてある物理パスの構造がそのまま名前空間に相当する階層。ソースコード中にはパッケージ名を書かない)
ちなみに、名前空間の外をグローバルスコープという。
暗黙的な型指定
C#:
var i = 10; // i はint型になる
C++ではauto
動的型付け
static void Main() { Add(1, 2); Add("a", "b"); } static void Add (dynamic x, dynamic y) { x = x + y; }
ローカル定数
constをつければローカル定数を作れる
+演算子
C#では、+演算子を文字列の連結やデリゲートの結合に使える。
フォークスルー
C#でのみ、case文でのフォークスルーが禁止されている。使いたいならgoto文を使う
switch(x) { case 0: // breakなどを書かないとコンパイルエラー case 1: goto case 2; case 2: break; default: break; }
※goto はブロック内から外に抜けられるが、逆はできない
Javaにgotoはない(今のところ)
foreach
for (int i : intArray) { }
のようにfor文をつかって実現可
isとas
C#には両方あり、C++にはどちらもなく、Javaにはasがありisのかわりにintanceofがある。
lock
同時に複数スレッドの実行を許さない。
C++にはない、Javaあsynchronizedを使う。
C#はlockステートメントがMonitorクラスを使って実装されるがJavaではJVMの機能として実装される。
とりあえずこんなところかな。今日のところはこれまでにしておきます
SmartEyeGlass用アプリを1から作る
Android Studioで適当な名前のプロジェクトを作成
Target DeviceをGlassにする
あとはNextを選択してFinishでサンプルプロジェクトが立ち上がる
Android Manifestをインクルード
AndroidManifest.xmlをプロジェクトにインクルードする。
すでにAndroidManifest.xmlがある場合は、サンプルプロジェクト内のapp/manifesestsにこのファイルが入っているのが確認できるのでそれを真似するFile/New/Import Moduleを選択
SmartExtensionAPIとSmartExtensionUtilsとSmartEyeGlassAPIをプロジェクトにインポートするbuild.gradleの一番下に以下を記述
dependencies { compile project(':SmartExtensionAPI') compile project(':SmartExtensionUtils') compile project(':SmartEyeglassAPI') }
これを記述しないとimportができないので注意
ここまででひと段落。
次はjavaクラスを追加していきます
その際に最低限必要なクラスは
Constants
BroadcastReseiver
ExtensionService
RegistrationInformation
ControlExtension
PreferenceActivity
あると便利なクラスとして
ScreenSize
があります。これらを
- 基本となるクラスを継承する
Constantsクラスはそのままjavaフォルダ下にコピー
BroadcastReseiver、ExtensionService、RegistrationInformation、ScreenSizeはそれぞれを継承したクラスがあるはずなので、それらをうまい名前に変えてコピー
これらは基本的に中身はそんなに変えなくていいはず
2. ControlExtensionとPreferenceActivityを継承したjavaクラスを作る
public class SampleControlExtension extends ControlExtension {}
public class MainActivity extends PreferenceActivity {}
ControlExtensionclassを継承することで、defineやディスプレイのレイアウト、イベントリスナーの作成、イベントハンドラーの定義、デバイスセンサーからのデータ取得を行える
(具体的にはSmartEyeglassControlUtilsを使えば大体の操作ができる)
もし、Android端末では何も行わないならばPreferenceActivityには何も記述しない
ここまで出来れば下の図のような配置になっているはず
3. layoutを作る
app/res/にlayout.xmlを作り、テキストなど適当に配置する
(ここはスルーしてもいい)
4. SampleControlExtensionを作る
ここではグラスにHello Worldを表示するだけの機能を持たせたクラスとする
public class SampleControlExtension extends ControlExtension { private final SmartEyeglassControlUtils utils; private static final int SMARTEYEGLASS_API_VERSION = 1; public SampleControlExtension(Context context, String hostAppPackageName) { super(context, hostAppPackageName); // utilの初期化 utils = new SmartEyeglassControlUtils(hostAppPackageName, null); utils.setRequiredApiVersion(SMARTEYEGLASS_API_VERSION); utils.activate(context); updateLayout(); } @Override public void onResume() { updateLayout(); super.onResume(); } @Override public void onDestroy() { utils.deactivate(); } @Override public void onTouch(final ControlTouchEvent event) { super.onTouch(event); } private void updateLayout() { showLayout(R.layout.layout, null); sendText(R.id.sample_text, "Hello World!"); } }
以上!これで動くものは作れます(はず)
+α
UIの作成
SmartEyeGlassで一番上のレイヤーはcard layerと呼ばれる層で、アプリケーションを選択することができる。
WidgetAPIを使うことで、アプリの最初のアイコンを作ることができる。
詳しくはここWidgets | Sony Developer Worldを見る。
例)HelloLayouts サンプル
XML Layout definitionで使うディスプレイのサイズを定義する。
data Bundle with run-time data を作成。
ControlExtensionを継承したクラス内でSmartEyeglassControlUtils.showLayout()
を使うことでディスプレイに表示させている。
イベントハンドラの追加
次に、いつ表示するかを決めなければいけない。その方法は2つあり
・built-in event callbackをoverrideする ・イベントリスナーを作成し、ハンドラーのコールバックを定義する
があります。
built-in event callbackをoverride
onTap()
やonKey()
などの基本操作は備わっており、たとえばメニュー画面からアプリがタップされたら起動します。
その動作を改造したい場合は、改造したい関数をoverrideすればよい。
イベントリスナーの作成
SmartEyeglassEventListenerを継承することで、独自のリスナーやハンドラを定義できる。
ここでいうリスナーとハンドラは、
イベントハンドラー: イベントに対して処理を定義したメソッド。
イベントリスナー: イベントに対して処理を結びつける仕組み。
であると考えます。(自分は)
例としては
private final SmartEyeglassEventListener mSmartEyeglassEventListener = new MySmartEyeglassEventListener(); class MySmartEyeglassEventListener extends SmartEyeglassEventListener { @Override public void onCameraReceived(CameraEvent event) { } @Override public void onCameraErrorReceived(int error) { } @Override public void onCameraReceivedFile(String filePath) { } @Override public void onRecordingStatus(long timeInMs, long frames) { } }
のように各イベントごとに処理をoverrideする。
3. テストする
実機でもエミュレータでもいいのでテストしてみる。
GooglePlayに公開する際には、説明に“SmartEyeglass”を記載する。
以上で簡単なプロジェクト作成に必要なものたちを紹介しました。
SmartEyeGlass開発記 〜サンプルapkをビルド〜
久しぶりの更新です。
英語の論文を書いていたり、就活となかなかコードを書かない日が続いていました。
それらがひと段落つき(つつあり)、ちょうど新しいおもちゃである
SonyのSmartEyeGlass
を手に入れたので、それのアプリでも作ろうかと思います。
まだまだ画面が小さいなど、制限はありますが何か面白い便利なものでも作りたいなと。
自分の開発環境は、
MacBook Pro15inch(2015モデル)
SmartEyeGlass
GalaxyS2 (Android4.4.2)
を使います。
基本はSony公式(http://developer.sonymobile.com/ja/smarteyeglass/developer-tools/#seg-header )をみて進めるつもりです。英語で書かれてるけどだけど意外と読みやすい
それでは、SmartEyeGlass上でHelloWorld!を表示させるぞーー!
Android Studioのインストール
これは開発を行ううえで必要となります。そんなに難しいことではないので、お使いの環境に合わせてインストールしてください。
Sony-SmartEyeGlass-SDKのインストール
- IDE を開いてAndroid SDK Managerを開く
- Android SDK ManagerのメニューにあるToolsから、Manage Add-on Sitesを選択
- User Defined Sitesをクリックして、newを選択
- URLに(http://dl.developer.sony.com/wearables/sdks/Sony-SmartEyeglass-SDK.xml)を入力してOK
- Android SDK Manager に戻り、Android 4.4.2 (API 19)の中にあるSmartEyeglass SDKにチェックをつけてインストール
SDK内は以下のようになっている
1. SDK_root/docs/reference/
APIリファレンスとライブラリが含まれる
2. SDK_root/samples/
Android Studio用 のサンプルが入ってる。デモ用
3. SDK_root/apks/
コンパイル済みのapkファイルが入っている
4. SDK_root/apks/SmartEyeglassEmulator.apk
実機テストするために必要なエミュレータ。実機にインストールする
5. SDK_root/apks/samples/
apkのサンプルが入っている
サンプルをAndroid Studioで開いてみる
- Android Studioを開き、既存のプロジェクトを開く
- ~/Library/Android/sdk/add-ons/addon-sony_smarteyeglass_sdk-sony-19/samples下にあるどれか開きたいやつを選択し、開いてみる
- いろいろ覗く
テスト環境を整え、サンプルapkを使ってテストしてみる
- SmartConnectとSmartEyeglassをGooglePlayをAndroid端末にインストール(Android4.4以上必要)
- 端末をPCにさして、コマンド
adb install SmartEyeglassEmulator.apk
をうつ。adbなんてないよ〜って言われたら、adbへのパスを通すため、
~/.bash_profileに
export PATH=$PATH:どこか/Android/sdk/platform-tools
を追記して、
source ~/.bash_profile
すればパスが通る。もちろん上にある”どこか”については各自の環境に合わせてください。 3. 適当なapkをインストールしてみる もうapkを使用できる準備は整った。たとえば他のサンプルである
adb install HelloWorld.apk
を行えば端末にアプリがインストールされ、SmartEyeGlassが端末と繋がっていればSmartEyeGlass上にも同じアプリが表示されるはずである。
SmartEyeGlass用エミュレータも存在しますが、自分はグラス端末を持っているので実機(グラス端末)を使ってデバッグでいきます。 Android端末にSmartEyeGlass-Emulaterというアプリが入っているはずなので、それを実行すればグラス端末と同じ画面が確認できるので非常に便利。
以上でビルドまでできるようになりました。
HelloWorldという文字をSmartEyeGlassで見るのはなかなか嬉しいものですね。
pngからepsへの変換(Mac)
久しぶりの更新
macでepsの画像を作るには convert コマンドを使えば良い。
$ brew install imagemagick $ convert *.png *.eps
これで出来てしまう。
ただ、サイズが10倍以上になるので注意が必要
Macbookの中の容量を整理
フォルダの容量を調べる
ルート直下から深さ1のもののファイルの大きさを調べるコマンドがある。
sudo du -hxd 1 /
これを深さ5までとして一括検索するコマンドは
sudo du -gxd 5 / | awk '$1 >= 5{print}'
であり、単位はGBで出てくる。
あとは、いらなそうなファイルを削除
条件分岐のいろいろ
フォークスルー
例えばswitch文はC, C++で使われているがC#では禁止されているらしい。
case内でのbreakのし忘れが頻繁におこったためだとか
goto
goto文はifやswitchと違い、無条件に処理の流れを変える命令。そのため、あまり推奨されない。以下の2つの場合にのみ使うことがある
switch文でのgoto文の使用
switch (hoge) { case 1: goto case 2; case 2: // hogeが1か2だった場合の処理 break; default: break; }
for文をぬけ出すための処理
以下のように、for文が2つ以上囲んである場合、その中から抜け出すにはgotを使う。なぜならbreakだとfor(j)からのみぬけ出すことになるから。
for (int i = 0;; i++) { for (int j = 0;; j++) { if (/*for文全部から抜け出したい*/) { goto LOOPEND; } } } LOOPEND: ;
Linuxで接続待ち(中)のポートを切る方法
netstat -a | grep localhost
とコマンドを打つと、接続がきれたsshを終了させるか待ち状態になっていることがある。
そのポートを閉じたいときは-p
オプションをつけるとプロセスIDが左に表示されるので
kill <PID>
で閉じることができる