技術備忘録・キャリアの見直し・情報収集など。


スキルの棚卸②

訳あって今振り返りをしたかった!

もっと開発やりたいです、そろそろ別の現場行きたいです、
みたいな希望を上長面談で言ったりして。
移動させてもらったんだけど、見事に会社都合で振り回された結果、3か月で退場。
体感だけど7~8割は政治のせいなのに思いっきり個人のせいにされたんだよなー。

よかったことは、上長との相性がよかったことと、 スケジュールとか仕様の握りがダルダルではなかったこと!

続きを読む

経験タスク

Webアプリ開発

Webアプリ開発なんて新人研修の時ぐらいしかやってない。
技術的にはRuby(Rails), Git(sourcetree)ぐらいだけど、
Rubyは全然身についた気がしないし今も活かせてるのはGitかな。

あとは、DBはPostgreSQLSQLiteを使い分けていて
記法の差分を吸収するのにラッパークラスで処理するのだなーと学んだり。

作業はというと、軽微な機能追加だったり修正対応やってました。
新しいものがドバーッと来たので全部中途半端になってしまったのが反省点。
スピート重視して理解が疎かになったり、備忘録とかまとめていなかったり…。
RubyMVC?Git?js?ajax?むり!パンクする!みたいな。

その他の観点

学んだこと(技術外)

・その現場に合った作業メモの書き方を考えられた
 複数案件を持ちつつチケットも細かかったから、同時進行が常だったんだよね。

 項番/案件名/チケット番号/概要/ステータス
 ①【案件A】# XXXXX ○○の修正(プルリク済)

…という感じ。あとは適当に時間区切ってメモしていけばOK。
メモの先頭にリストアップしておいて、項番ふって追記するとか。
個人的には結構やりやすかったなー。どれぐらい時間かけてるか把握するのってダイジよね。
しかし「俯瞰的なスケジュールがわかりにくい」とか書いてあるので改善の余地あり。

モチベが上がった時

うーん、難しい。終始必死だった気がする。
がっつりWebアプリ身につけるぞー!って感じでもなく。

モチベが下がった時

「やりながら学ぶ」のが出来ないぐらい負荷が高い時かなぁ。
基礎の基礎レベルで良いから別途勉強時間がほしい!と、思ってもそれができない時。
わかんないのに、それ以上の情報なんて捌き切れない!!!ってなる。
未経験内容ばかりをこなす日々なので、脳のリソースもなければ勉強する気力も…
って感じなんだけどね。
出来ないことを要求されるって結構ストレス。

今後伸ばしたいスキル

なんだろ。技術的にはあんまりピンと来てない。
純粋にメンバーとして参画して作業しながらお勉強する、って感じだったもんなー。
強いて言うなら、わからないことを捌くスキル…?
自分でまとめられなくなったら、まとまってなくても上長に相談する…。
とか思ったけどこれはただの反省点な気がする。


いやー、これだけ見ると、収穫は???って不安になるなぁ。
ただちょっと思うのは、Webアプリよりスマホアプリの方が自分に合うのでは?
と、なんとなーく感じる比較対象が出来たなって。曲がりなりにも。

あ、あと、MVCを少しかじったおかげでMVPに入りやすかった気がする。
それぐらいかなー!後続の案件に繋がってたりするのは。

SharedPreferenceにオブジェクトを保存する

SharedPreferenceに保存できるデータ型って結構少ないんですが、
ひと手間加えると自由度が高くなります。 自分で定義した型のまま持てたりね!
今回はその方法です。

SharedPreferenceを扱うラッパークラス(PreferenceManager)を定義してある前提で サクサクっと。
⇒ラッパークラスの定義はこちら aimy74.hatenablog.com

最終的に保存する際はString型に落ち着くのですが、
JSON形式にすればオブジェクト(として扱いたいデータ)をPreferenceに簡単に保存できます。

続きを読む

Gsonライブラリ導入

JavaオブジェクトとJSONデータの変換を行うライブラリです。Google提供。
https://github.com/google/gson

Gradleに以下を追記。以上!

dependencies {
  implementation 'com.google.code.gson:gson:2.8.6'
}

実装

  • 保存したいオブジェクトの定義
public class Person{
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName(){return this.name}

    public int getAge(){return this.age}
}
  • 保存・取得
    // 保存する
    // 保存したいオブジェクトを生成する
    Person person = new Person("tanaka",25);

    Gson gson = new Gson();

    // Json形式に変換して登録
    String jStr = gson.toJson(person, Person.class);
    PreferenceManager.setObject(getApplicationContext(),jStr);

    // ------------------

    // 取得する
    Person personResult.fronJson(PreferenceManager.getObject(getApplicationContext()), Person.class);
    String name = personResult.getName();
    int age = personResult.getAge();

Model操作と体感そんなに変わらず書けて良い感じ。

SharedPreferenceおさらい

ネタはある(というか書き溜めている)のに更新できていない…。
ので、職場で更新する暴挙に出た!
年末だし、レスポンス遅いし、やることはやってるからいいよね。。

「Gson」というライブラリを使うにあたって、Preferenceをおさらいしておこう~
と、急に思い立ったのでざっくりまとめます。

続きを読む

そもそもSharedPreferenceとは

ざっくりこんな感じ。
Androidバイス内にデータを保存する仕組みだよ
・SharedPreference自体はXMLファイルだよ
・アプリを削除しなければ永続的にデータ保持できるよ
・キー・バリュー形式で保存するよ
・環境設定の保存などによく使われるよ
・保存できるデータ型には String, int, float, long, boolean, Set<String>があるよ

基本操作

    // インスタンスの取得
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    SharedPreferences.Editor editor = prefs.edit();

    // データの書き込み
    editor.putString(key, value);
    editor.apply();

    // データの書き出し
    String test = prefs.getString(key);

SharedPreferences.Editor  |  Android Developers

個人的にやっている実装方法

ラッパークラスを作っておくと、外からそれを呼ぶだけでOKになるので楽!
★別ページで使用するメソッドについてはこちら。
手を加えればオブジェクトっぽいものも保存できて便利です。 aimy74.hatenablog.com

public class PreferenceManager {
    // KEYS
    private static final String KEY_SAMPLE = "keySample";
    private static final String KEY_OBJECT = "keyObject";
    // VALUES(デフォルト定義など、必要であれば)

    // テキストを保存する
    public static void setText(Context context, String value){
        save(context, KEY_SAMPLE, value);
    }

    // テキストを読み込む
    public static String getText(Context context) {
        return readString(context, KEY_SAMPLE);
    }

    // ★別ページで使用する
    public static void setObject(Context context, String value){
        save(context, KEY_OBJECT, value);
    }
    public static String getObject(Context context) {
        return readString(context, KEY_OBJECT);
    }

    // 書き込みメソッドのラッパー
    private static void save(Context context, String key, String value) {
        SharedPreferences prefs = android.preference.PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(key, value);
        editor.apply();
    }

    // 読み出しメソッドのラッパー
    private static String read(Context context, String key) {
        SharedPreferences prefs = android.preference.PreferenceManager.getDefaultSharedPreferences(context);
        return prefs.getString(key, "");
    }
}

呼ぶときはこんな感じ。

    // 書き込み
    PreferenceManager.setText(getAplicationContext(),"テスト");

    // 読み出し
    String sampleText = PreferenceManager.setText(getAplicationContext());

以上、個人的なおさらいでした。

SQLiteおさらい

AndroidSQLite。初歩の初歩おさらい。
アプリの勝手がまだまだわからない。追加機能でDBに変更ありましたー!とかって
どうやって検知してどうやって反映するのか。

忘れないうちにメモ。

続きを読む

SQLiteOpenHelperの継承クラス作成

まずはこれから。 SQLiteOpenHelperを継承したクラスを作成。

public class TestOpenHelper extends SQLiteOpenHelper {
    // データーベースのバージョン
    // これを上げていくことでDBのver.が上がった判定になる
    private static final int DATABASE_VERSION = 1;
    // データーベース名
    private static final String DATABASE_NAME = "TestDB.db";

    private Context mContext;

    TestOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        mContext = context;
    }

    // 指定されたデータベースが無い場合に、自動的に実行
    @Override
    public void onCreate(SQLiteDatabase db) {
        // テーブル作成
    }

    // 実際に存在しているデータベースのバージョンが違うときに実行
    // ※作成済みバージョン < 定数として宣言したバージョン
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        // テーブル追加など
    }
}

※バージョン比較はアプリ自体ではなく、あくまでもDBのバージョンで行われる

考えたこと

単純にDBのver.が上がるパターン

初期のDB構造が生成されている⇒アップデート時に追加した処理が反映される ⇒わかる
単純に追加だとか修正が乗っかるイメージ。

インストール時はver2.0以降だけどそもそも新規インストールのパターン

指定されたDBがない場合、onCreateがまず走る。
ので、そもそもバージョン比較まで話が至らない⇒onUpgrade呼ばれないのでは? (バージョン比較して差異がある場合に走るメソッドなので)

…ということは。

  • インストール用に、追加で組み込みたい処理もプラスした生成処理を記述(onCreate)

  • アップデート用に、追加で組み込みたい処理を単体で記述(onUpgrade)

みたいになるのかなー、と思って調べてみたらやっぱりそうだった。

意識しないとハマりそうなパターン

そしてonUpgradeに処理を書くとして、
「アップデートを保留にしていて、"ver.1⇒ver3"のように間を飛ばしてアップデートされる」
というケースの考慮も必要だった。なるほど。言われないとやらかしそう…。 追加処理に関しては、独立させて作っておいてonCreateからもonUpdateからも呼ぶとかにするとよいのかな。

参考サイト

AlertDialogのカスタム方法

突然の技術備忘。
オリジナルレイアウト(XML)を使わないカスタム方法について。
見た目をいじるならAlertDialogFragmentかなと思ってたけど、
XML定義しなくても標準出力で結構できるじゃん!と思ったのでメモ。

あと、Markdownも触り始めたのでその練習も兼ねてますー。

続きを読む

1. 基本形

    // ダイアログ生成処理
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setTitle("タイトル");
    builder.setMessage("メッセージ");
    // 処理を実装する場合はリスナーをセット
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            // クリック時の処理
        }
    });
    builder.setNegativeButton("NG", null);
    builder.setNeutralButton("NEUTRAL", null);
    builder.show(); // 表示

f:id:aimy74:20191125212108p:plain:w200

2. タイトル・メッセージのカスタム

  • タイトルカスタム
    // カスタムしたい内容
    TextView title = new TextView(getApplicationContext());
    title.setText("カスタムタイトル");
    title.setTextSize(30); //テキストサイズ
    title.setPadding(0,30,0,30); // 余白
    title.setTextColor(Color.BLUE); //テキストカラー
    title.setGravity(Gravity.CENTER_HORIZONTAL); // 中央配置

    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setCustomTitle(title); // カスタムタイトルをセット
    builder.setMessage("メッセージ");
    // 中略
    builder.show(); // 表示

f:id:aimy74:20191125212638p:plain:w200

  • メッセージカスタム
    // カスタムしたい内容
    TextView message = new TextView(getApplicationContext());
    message.setText("カスタムメッセージ");
    message.setTextColor(Color.YELLOW); //テキストカラー
    message.setBackgroundColor(Color.GRAY); // 背景色

    // ダイアログ生成処理
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setTitle("タイトル");
    builder.setView(message); // カスタムメッセージをセット
    // 中略
    builder.show(); // 表示

f:id:aimy74:20191125212944p:plain:w200

3. 画像を埋め込む

  • タイトル
    // ダイアログ生成処理
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setTitle("タイトル");
    builder.setMessage("メッセージ");
    builder.setIcon(R.drawable.sample) // アイコンのリソースを指定
    // 中略
    builder.show(); // 表示

f:id:aimy74:20191125213059p:plain:w200

  • メッセージ
    // 埋めこむ画像の設定
    ImageView image = new ImageView(getApplicationContext());
    image.setImageResource(R.drawable.sample_image);

    // ダイアログ生成処理
    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setTitle("タイトル");
    builder.setMessage("メッセージ");
    builder.setView(image); // 画像をセット
    // 中略
    builder.show(); // 表示

f:id:aimy74:20191127231244p:plain

参考

スキルの棚卸①

現場区切りでまとめてみようかと。

研修後、客先常駐スタート。最初の現場にいたのは2年弱ぐらいです。
ちなみにこの時点でJavaが2か月程度。
ざっっっっっくり「Webアプリってこんな感じなんだ。ふ~ん。」ぐらい!

言語:VBA (Access / Excel)
DB  :Access, SQL Server

さて、ふりかえっていこうー!

  •  経験タスク
    • 集計ツール作成
    • BIツールの設計書作成
    • BI用のデータマート作成
    • 新人教育
  •  その他の観点
    • 学んだこと(技術外)
    • モチベが上がった時
    • モチベが下がった時
    • 今後伸ばしたいスキル
続きを読む

はじめまして。

初回なので無難に自己紹介。

異業種からSEに転職して3年ほど経ちます。

駆け出しとか初級と言うには年月が経ちすぎている気がするけれども、

その割に見合ったスキルがついてないなーと日々悶々。

毛色の違う案件ばかり転々としていたので、

ガッツリ開発できてるのってここ1年ぐらいかも。(VBA期間は除く)

 

*- スキル -* 

Java / Ruby (Ruby on Rails) / VBA (Access) / SQL (PostgreSQL / SQLite) / Tableau

 

技術系の備忘であったり、スキルの棚卸だったり、情報収集だったり、

主にそんな内容になるかと思います。あとは雑記も。

 

先日アプリのリリースが終わって、思うことがたくさんあったんだよなぁ…。

なので、アウトプットの習慣を作っていきたいなと。

 「今のままじゃマズイ…」を放置せず行動に移していくのが第一歩!