2013年9月30日月曜日

AndroidのlargeHeap(オレと皆さま調べ)

手持ちの端末+αでlargeHeap有効時のヒープサイズを調べてみました。

結果

まずは結果から。
こんな感じ。

[2016/06/03 3機種追加]
今回の追加分は@_postNogenoraさんに情報提供いただいたNexus 6/SBM104SHと
手持ちのSC-05G。
ありがとうございます!

MODEL API Level getMemoryClass() getLargeMemoryClass() ご協力
Nexus
Nexus 6 23 256MB 512MB @_postNogenoraさん
Nexus 10 17 192MB 512MB オレ
Nexus 7(2013) 18 192MB 512MB @kimukou2628さん
Nexus 7(2012) 18 64MB 384MB オレ
Nexus 5 19 192MB 512MB オレ
Nexus 4 18 192MB 512MB オレ
Galaxy Nexus 17 96MB 256MB オレ
Nexus S 16 48MB 128MB オレ
docomo
SC-05G 23 256MB 512MB オレ
F-05F 19 192MB 512MB @wakuimasashiさん
SH-04F 19 128MB 384MB @wakuimasashiさん
SH-05F 17 128MB 384MB @wakuimasashiさん
SO-04E 16 128MB 384MB オレ
SO-03E 16 128MB 384MB オレ
SO-02E 16 128MB 384MB オレ
SH-04E 16 64MB 256MB オレ
F-10D 15 72MB 256MB オレ
SO-05D 15 64MB 256MB オレ
SO-03D 15 64MB 256MB オレ
N-02E 15 64MB 256MB @takkeさん
SC-06D 15 64MB 256MB @kimukou2628さん
SO-01F 17 192MB 512MB オレ
F-01F 17 128MB 384MB オレ
SC-01F 18 128MB 512MB オレ
L-01F 17 128MB 256MB オレ
F-07E 17 128MB 384MB オレ
L-05E 17 96MB 256MB オレ
SH-07E 17 64MB 256MB オレ
N-06E 17 128MB 384MB オレ
SH-06E 17 128MB 384MB オレ
SC-04E 17 128MB 512MB オレ
HW-03E 16 256MB 256MB オレ
L-04E 16 128MB 256MB オレ
dtab01 16 256MB 256MB オレ
P-02E 16 128MB 384MB オレ
F-03E 15 72MB 256MB オレ
SH-02E 15 64MB 256MB オレ
HW-01E 15 128MB 256MB オレ
SO-01E 16 64MB 256MB オレ
SH-01E 15 54MB 160MB オレ
P-08D 15 48MB 256MB オレ
SH-10D 15 64MB 256MB オレ
F-11D 15 84MB 128MB オレ
L-06D 15 70MB 256MB オレ
T-02D 15 72MB 256MB オレ
N-07D 15 64MB 256MB オレ
L-05D 15 64MB 256MB オレ
SH-09D 15 64MB 256MB オレ
F-09D 15 72MB 128MB オレ
SH-07D 15 48MB 128MB オレ
SC-05D 15 64MB 256MB オレ
au
SOL25 19 143MB 463MB @wakuimasashiさん
SCL23 19 128MB 512MB @wakuimasashiさん
SOL23 17 192MB 512MB オレ
SCL22 18 128MB 512MB オレ
SHL22 17 64MB 256MB オレ
KYY21 17 96MB 256MB オレ
HTL22 16 192MB 384MB オレ
SOL22 17 192MB 512MB @hikaru__mさん
SOL22 16 128MB 384MB オレ
HTL21 16 128MB 256MB @takkeさん
SCL21 15 64MB 256MB オレ
FJL21 15 72MB 256MB オレ
IS17SH 15 54MB 160MB オレ
ISW16SH 15 64MB 256MB オレ
IS15SH 15 54MB 160MB オレ
ISW13HT 15 48MB 128MB オレ
IS12S 15 64MB 256MB @takkeさん
IS11LG 15 64MB 64MB オレ
ISW11SC 15 64MB 256MB オレ
ISW11F 15 72MB 256MB オレ
URBANO PROGRESSO 15 64MB 256MB オレ
SoftBank
SBM107SH 15 64MB 256MB オレ
SBM104SH 15 64MB 256MB @_postNogenoraさん

IS11LGはlargeHeap有効時もヒープサイズは増えないようです。
IS11LGだけなのか、他にも同様の端末があるのか分かりませんがリファレンスをみると

ActivityManager | Android Developers http://developer.android.com/reference/android/app/ActivityManager.html#getLargeMemoryClass()

This may be the same size as getMemoryClass() on memory constrained devices
とあるので、許容動作の模様。

コード

検証用のコードは、こんな感じ。
package com.tytosoft.largeheapchecker;

import android.app.Activity;
import android.app.ActivityManager;
import android.os.Build;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

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

        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        String info = "MODEL : " + Build.MODEL + "\n"
                + "API Level : " + Build.VERSION.SDK_INT + "\n"
                + "getMemoryClass() : " + activityManager.getMemoryClass() + "MB\n"
                + "getLargeMemoryClass() : " + activityManager.getLargeMemoryClass() + "MB";

        TextView textView = (TextView) findViewById(R.id.textview);
        textView.setText(info);
    }

}

getMemoryClass() : largeHeap無効時のヒープサイズ
getLargeMemoryClass() : largeHeap有効時のヒープサイズ
だと思っている。

アプリ

検証に使ったアプリをGoogle Playにアップしてみました。

Get it on Google Play

largeHeapはAPI Level 11から使えますが、3.xタブレットはもう考慮しなくて良いと思っているのでminSdkVersionは14としています。

お手持ちの端末で動かしたスクリーンショットなどをこちらまで送っていただければ、上記の表に追加したり、しなかったりします。

2013年9月29日日曜日

Androidでパスワード付きZipファイルを展開する方法

2013/11/09 In-Memoryで捌く方法を追記

ライブラリ

Zip4jというライブラリを使用します。
Zip4j - Java library to handle Zip files
http://www.lingala.net/zip4j/

Zip4jのライセンスはApache License, Version 2.0。
Zip4j - About
http://www.lingala.net/zip4j/about.php

プロジェクトにライブラリを追加

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}
apply plugin: 'android'

repositories {
    mavenCentral()
}

android {
    compileSdkVersion 18
    buildToolsVersion "18.0.1"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 18
    }
}

dependencies {
    compile 'net.lingala.zip4j:zip4j:1.3.1'
}

build.gradleにライブラリを追加する時は、こちらのサイトが便利です。
Gradle, please
http://gradleplease.appspot.com/

Zip4jで検索するとこんな感じに表示されますので、あとはbuild.gradleにコピペすればOKです。

Eclipseで開発している場合は下記のページからjarファイルをダウンロードしてlibsディレクトリに配置します。
Zip4j - Java library to handle Zip files
http://www.lingala.net/zip4j/download.php

サンプルコード

package com.example.passzip;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;

public class MainActivity extends Activity {

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

        String zipFilePath = Environment.getExternalStorageDirectory().getPath() + "/PassZip/hoge.zip";
        String destinationPath = Environment.getExternalStorageDirectory().getPath() + "/PassZip/";
        String password = "hoge";
        try {
            ZipFile zipFile = new ZipFile(zipFilePath);
            if (zipFile.isEncrypted()) {
                zipFile.setPassword(password);
            }
            zipFile.extractAll(destinationPath);
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }

}
sdcard/PassZip/ディレクトリにあるパスワード付きZipファイルhoge.zipを同じディレクトリに展開するサンプルになっています。
Zipファイルの中身はfoo.txtが入ったhogeディレクトリです。
Zipファイルのパスワードはhogeとします。
外部ストレージに書き込みを行いますのでマニフェストファイルに
android.permission.WRITE_EXTERNAL_STORAGE
の宣言が必要です。

サンプルコードでは簡略化のため、UIスレッド上でZipの展開処理を行っています。
実際にアプリで使用する場合はAsyncTaskなどを使ってUIスレッドをブロックしないようにします。
エラー処理も省略していますので適宜エラー処理を行います。

動作確認

動作確認は
・Xperia Z(Android OS 4.1.2)
・IS14SH(Android OS 2.3.5)
で行いました。

アプリ実行前
アプリ実行後
実機のファイラーアプリからfoo.txtを確認したところ、テキストファイルの内容が表示されましたので正常にパスワード付きZipファイルの展開が行われているようです。

In-Memory(2013/11/09 追記)

上記のサンプルではZipファイルをストレージに展開してから使用しましたが、In-Memoryで捌く方法はこんな感じです。
このサンプルではgetExternalFilesDir()なディレクトリにある、test.zipの中身(ic_launcher.png)を読み込んでImageViewに表示しています。

ZipFile zipFile = null;
FileHeader fileHeader = null;
InputStream inputStream = null;
Bitmap bitmap = null;
try {                                                                         
    zipFile = new ZipFile(getExternalFilesDir(null).getPath() + "/test.zip");
    if (zipFile.isEncrypted()) {                                              
        zipFile.setPassword("password");                                      
    }                                                                         
    String filePath = "ic_launcher.png"; // アーカイブ内のファイルパス                     
    fileHeader = zipFile.getFileHeader(filePath);                             
    inputStream = zipFile.getInputStream(fileHeader);                         
    bitmap = BitmapFactory.decodeStream(inputStream);                         
    inputStream.close();                                                      
} catch (ZipException e) {                                                    
    // TODO: error handling                                                   
} catch (IOException e) {                                                     
    // TODO: error handling                                                   
}                                                                             
                                                                              
ImageView imageView = (ImageView) findViewById(R.id.image_view);              
imageView.setImageBitmap(bitmap);                                             

参考サイト

こちらのサイトを参考にさせていただきました。
ありがとうございます。
shinodogg.com
パスワード付きZipファイルをJava(Zip4j)で
http://shinodogg.com/?p=4601

2013年9月6日金曜日

Android StudioでGit(core.autocrlf)


Android Studioで作ったプロジェクトをコミットするときに出た、警告ダイアログの対処メモ。

環境

・Mac OS X 10.8.4
・Android Studio (I/O Preview) 0.2.6

原因

Android Studioのデフォルト設定では下記の
[Warn if CRLF line separators are about to be committed]
にチェックが入っている。
CRLFラインセパレータがコミットされようとしている場合に警告を表示するという設定。
core.autocrlfが未設定だったり、falseに設定されていると上記の警告ダイアログが表示される。

CRLFラインセパレータなファイルとはgradlew.bat。
gradlew.batをエディタで開いてステータスバーを確認すると確かにCRLFとある。
Windows環境で使うファイルですからね。

core.autocrlfとは

コミット時の改行コードの扱いを決めるもののようです。

こちらのサイトを参考にさせていただきました。
WindowsやMacなど様々なOSからGitを使うときの改行コードの扱い » tech-tec
http://tech-tec.com/archives/107

対処

冒頭のダイアログにもありますが
git config --global core.autocrlf input
の設定を行うと解決します。

コマンドラインから上記コマンドを実行して、コミットを行ってもよいですし
冒頭のダイアログで[Fix and Commit]ボタンをクリックすると自動でcore.autocrlfをinputに設定した後、コミットを行ってくれます。

core.autocrlfの設定確認

<User Home>/.gitconfigをテキストエディタで開く
or
ターミナルからgit config -l コマンドで確認できる。

2013年9月4日水曜日

Android StudioでGit(Changesツールウィンドウを使ってみた)

こちらのBlog記事に

Java Day Tokyo 2013の裏方で takezoe さんをIntelliJ派に洗脳してた - marsのメモ
http://d.hatena.ne.jp/masanobuimai/20130518/1368867743

バージョン管理に関するモロモロの操作は,ProjectツールウィンドウよりChangesツールウィンドウのほうが便利に使えるようにできてます
とありましたので、Android StudioのChangesツールウィンドウをつかってみたメモ。

環境

・Mac OS X 10.8.4
・Android Studio (I/O Preview) 0.2.6
 Keymap Mac OS X 10.5+

git init

[control] + [V]で[VCS Operations Popup...]を開く。
[4]の[Enable Version Control Integration...]を選択。

Gitを選択して[OK]ボタン。

.gitignore

Changesツールウィンドウを開く。
Unversioned Filesにバージョン管理されていないファイルが入っている。

プロジェクトに.gitignoreを追加。
※ .gitignoreの内容はこちらを参照
 Android Studioと.gitignore(2013/09/03版)
 http://neta-abc.blogspot.jp/2013/09/android-studiogitignore20130903.html

Unversioned Filesから、.gitignoreで除外したファイルが消える。

git add

↑のスクリーンショットのUnversioned FilesをDefaultにドラッグ&ドロップ。
↓はドラッグ&ドロップ後のスクリーンショット。

git commit

Defaultを選択した状態で、[Commit Changes]ボタン。
(ファイルを選択した状態で、[Commit Changes]ボタンをクリックするとファイルを個別にコミットできる)

コミットメッセージを入力して[Commit]ボタン。

コミットが完了するとDefaultは空に戻る。

以降はコードに変更を加えると、変更したファイルがDefaultに入るので
コミット->コード変更を繰り返す流れ。

2013年9月3日火曜日

Android StudioでGit(コミットとかブランチとか)

Android StudioでGitを使ってみたメモ。

環境

・Mac OS X 10.8.4
・Android Studio (I/O Preview) 0.2.6

コミット

コードに変更を加えるとエディタの左側の部分の色が変わるようだ。
(この例ではメソッドhoge()の追加が変更点)

変更があるファイルは文字色が水色に変わる模様。

コンテキストメニューから[Git] - [Commit Directory...]を選択。

適当にコミットメッセージを入力して[Commit]ボタンをクリック。

コンテキストメニューの[Git] - [Show History]を確認したところ
ちゃんとコミット出来ているようだ。


ブランチ

コンテキストメニューから[Git] - [Repository] - [Branches...]を選択。

[New Branch]を選択。

適当にブランチ名を入力して[OK]ボタンをクリック。

ブランチが作成され、Current Branchが「develop」に切り替わる。
Current Branchはステータスバーの右側に表示されている。

ブランチの切り替えは
コンテキストメニューから[Git] - [Repository] - [Branches...]を選択。
移動したいブランチを選んで[Checkout]を選択。

Twitterで@masanobuimaiさんに教えていただいたので追記。
ステータスバーの[Git: <ブランチ名>]のところをクリックすると、ブランチ作成・切り替えのメニューが開きます。

ブランチの作成・切り替えはステータスバーからの方が便利ですね。

Android Studioと.gitignore(2013/09/03版)

2013/09/02版に「.gradle/」を追加。

iosched(2013)の.gitignoreを見たところ
# gradle cacheとして除外されていたので。
(.gradle/配下のファイルの役割はよく分かっていない...)

僕の.gitignore(2013/09/03版)
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties

# Eclipse project files
.classpath
.project

# Proguard folder generated by Eclipse
# proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/

# Android Studio files
*/build/
gradle.properties

# gradle cache
.gradle/

# Mac OS .DS_Store file
.DS_Store

2013年9月2日月曜日

Android StudioでGit(git init 〜 Initial commitまで)

Android StudioでGitを使ってみたメモ。
(最終的にうまくいきませんでした...)

<2013.09.04追記>
オペレーションがイケテナカッタので
こちらに書き直しました。
Android StudioでGit(Changesツールウィンドウを使ってみた)
http://neta-abc.blogspot.jp/2013/09/android-studiogitchanges.html

環境

・Mac OS X 10.8.4
・Android Studio (I/O Preview) 0.2.6

git init

メニューの[VCS] - [Enable Version Control Integration...]をクリック。

プルダウンメニューからGitを選んで[OK]ボタンをクリック。

するとこんな感じになる。
Gitの管理対象だけど、まだgit addされていないファイルが赤文字になっているようだ。

Version Control Consoleを見るとgit initが行われた模様。
fatal: bad revision 'HEAD'とあるが、よく分からない...

.gitignore

ルートプロジェクトのルートディレクトリに.gitignoreファイルを配置する。
.gitignoreファイルの設定内容はこちらの記事を参照。
Android Studioと.gitignore
http://neta-abc.blogspot.jp/2013/09/android-studiogitignore.html
↑の.gitignoreに.gradle/を追加

するとこんな感じに。
.gitignoreで除外したファイルの文字色が白に変わった。

git add

ルートプロジェクトのルートディレクトリを選択した状態で右クリック。
[Git] - [Add to VCS]をクリック。

そうすると、Git管理対象ファイルの文字色が緑に変わる。

git commit

ルートプロジェクトのルートディレクトリを選択した状態で右クリック。
[Git] - [Commit Directory...]をクリック。

コミットメッセージを入力して[Commit]ボタンをクリック。

gradle-wrapper.propertiesファイルでWarningが出ますが、よくわからないのでそのまま[Commit]ボタンをクリック。。

Git管理対象ファイルの文字色が緑から白に変わる。

ターミナルから確認したところコミットはできました。

git statusで確認したところ
.gradle/がUntrackedだよと言われている...

Version Control Consoleで確認すると確かにgit addの時に.gradle/がaddされていない。
んー。。
.gradle/下のファイルをGitの管理対象にすべきか調べて出直して来ます...

iosched(2013)の.gitignoreの設定を確認したところ
.gradle/は除外対象になっていました。

Android Studioと.gitignore

Android Studioで作成したプロジェクトをGitで管理するときの.gitignoreの設定について試行錯誤中のメモ。

.gitignoreファイルとは

Gitの管理対象から除外したいファイル・ディレクトリを指定する設定ファイルです。

.gitignoreファイルのベース

.gitignoreのベースはこちらを使わせてもらいました。

github/gitignore · GitHub
https://github.com/github/gitignore

ココのAndroid.gitignoreがAndroidアプリプロジェクト用の.ignoreファイルです。

今のところ、Eclipse / Android Studio用を分けるつもりはないので、1ファイルでEclipse / Android StudioのAndroidアプリプロジェクトに対応できるようにします。

僕の.gitignore(2013/09/02版)

# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties

# Eclipse project files
.classpath
.project

# Proguard folder generated by Eclipse
# proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/

# Android Studio files
*/build/
gradle.properties

# Mac OS .DS_Store file
.DS_Store
ベースからの変更点は、
・*/build/下は除外対象
・gradle.propertiesは除外対象
(リリース用証明書のパスワードをココに記載しているので)

Android Studio絡みではないですが
・proguard/は除外対象から外す
(Eclipseでは管理対象にしてました。Android Studioだと*/build/proguard/の下にProGuard関連のファイルが生成されますので、今の設定ですと除外されます。ちょっと考えます。。)
・Mac OSのDS_STOREファイルは除外対象
という変更も入ってます。

つっこみお待ちしております。。