- Only the original thread that created a view hierarchy can touch its views
Original Thread으로만 UI를 변경하여야 함.
Main Thread 외의 새로 생성한 Thread를 이용하여 임의로 UI를 업데이트 할 경우 발생.
Handler를 이용하여 Main Thread를 간접적으로 사용하여하 함.
![]() |
그림 1 |
![]() |
그림 2 |
@Retention(용도)
@Target(범위)
public @interface XXX {
...
}
RetentionPolicy.java (java.lang.annotation)
/**
* @since 1.5
*/
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
* 컴파일러가 사용하고 클래스 파일 안에 포함되지 않음 (단순 주석용, 컴파일러용)
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
* 컴파일시 클래스 파일 안에 포함되나 VM에서 무시함
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
* 컴파일시 포함되고 VM에서 인식함
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
ElementType.java (java.lang.annotation)
/**
* @since 1.5
*/
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
* @hide 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
* @hide 1.8
*/
TYPE_USE
}
Bundle bundle = new Bundle(); bundle.putParcelable(EXTRA_DATA, xxx); intent.putExtra(EXTRA_DATA, bundle);
Bundle bundle = intent.getBundleExtra(EXTRA_DATA);if (bundle != null) { final XXX xxx = bundle.getParcelable(EXTA_DATA); }
public class Log {
public final static String TAG = "InputCommonTagName";
public static final boolean LOGV = true;
static final boolean LOGV_TAG = true;
static int mLine=0;
static String mName="";
static String mPkg="";
public static void v(String logMe) {
if(LOGV) {
StackTraceElement[] stack = (new Throwable()).getStackTrace();
mLine = stack[1].getLineNumber();
mName = stack[1].getMethodName();
mPkg = stack[1].getFileName();
android.util.Log.v(TAG, ""+mPkg+", "+mLine+" line, "+mName+"(), "+logMe);
}
}
public static void v(String tag, String logMe) {
if(LOGV_TAG) android.util.Log.v(tag, logMe);
}
}
Log.d("TAG_NAME", "$CLASS_NAME$ : $METHOD_NAME$()" : $content$);
groovyScript("def params = _3.collect {it + ' = [\" + ' + it + ' + \"]'}.join(', '); return '\"' + _1 + ' : ' + _2 + '()' + (params.empty ? '' : ' : ' + params) + '\"'", className(), methodName(), methodParameters())
Log.d($content$);
groovyScript("def params = _1.collect {it + '=\"+'+it}.join('+ \"'); return '\"' + (params.empty ? '' : params)", methodParameters())
groovyScript("def params = _1.collect {it + ' = [\" + ' + it + ' + \"]'}.join(', '); return '\"' + (params.empty ? '' : params) + '\"'", methodParameters())
Log.d("TAG_NAME", "$CLASS_NAME$ : $METHOD_NAME$() returned: " + $result$);
Log.d("returned : $result$=" + $result$);
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/styles/default.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<pre><code>
// to do
</code></pre>
http://www.igorware.com/tools/xml-escape
productFlavors 와 sourceSets 을 조합
productFlavors {
ABC {
}
DEF {
}
}
sourceSets {
ABC {
assets.srcDirs = ['src/main/assetsABC']
}
DEF {
assets.srcDirs = ['src/main/assetsDEF']
}
}
compile files('libsFolderName/name.jar') //compile fileTree(dir: 'libs', include: ['*.jar']) }
Xbootclasspath 설정
-Xbootclasspath/p:"Module Name"/"jar path"
gradle.projectsEvaluated { tasks.withType(JavaCompile) { options.compilerArgs.add('-Xbootclasspath/p:app/libs/xxx.jar') } }
cf> Xbootclasspath 에 대한 상세 설명은 아래 링크 참조
http://java.ihoney.pe.kr/27
(참조 : stackoverflow.com)
task nativeLibsToJar(type: Zip, description: 'create a jar archive of the native libs') { destinationDir file("libs") // jar 로 압축된 파일이 저장될 폴더 위치 baseName 'name' // jar 로 압축할 파일 이름 (위 dependencies 에서 사용될 name.jar)
extension 'jar' // 확장자 이름
from fileTree(dir: 'ExtClass', include: '**/*.class') //가져올 원본 class or so 파일
//into 'lib/' // jar로 압축하면서 만들 추가 폴더 이름. android class 파일들은 지정안하는게 나음.
} tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn(nativeLibsToJar) }
android {
... ... sourceSets { main { java { exclude '**/name.java'
} } } }
5. 빌드후 apk 이름 변경시키기
defaultConfig {project.ext.set("archivesBaseName", "name"); }6. 서명키
프로젝트 최상위 경로에 gradle.properties 파일 생성하여 아래 항목 작성
package 명에 대문자가 있을 경우 소문자로 변경후 clean 빌드하면 정상 동작한다.
Android Studio 에서 package rename 하는 방법은,
프로젝트 탭의 설정 아이콘 선택 -> "Compact Empty Middle Packages" uncheck -> 변경하고자 하는 폴더에서 마우스 우클릭 -> Refactor -> Rename 실행.
한글 오류 발생할 경우,
해당 파일 -> 메뉴 -> File -> file encoding 선택 -> x-window-949 선택 -> reload
-> 다시 메뉴 반복 file enconding 선택 -> utf-8 선택 -> convert
해당 소스 파일을 SDK\soruces\해당버전에 위치시킴
#!/usr/bin/perl
# SearchToNotUsePng.pl
# seesky89 20140826
# usage :
# Android Application 개발시 사용하지 않는 png 이미지 제거를 위해 만듬.
# cgywin(for Windows) 또는 리눅스에서 아래 명령 입력(상위 폴더기준)
# perl SearchToNotUsePng.pl
# 정확성을 위해 gen, bin 폴더는 삭제 필요.
use strict;
use warnings;
use File::Find;
use File::Find qw(find);
use Cwd;
my $dir = '.';
open FH, ">", "result.txt" or die "$!\n";
my $mainDir = getcwd;
print FH "Search to not use resource. you need to check.\n";
print FH $mainDir, "\n";
print FH "------------------------------------------------------------\n";
find(\&find_use_file, $dir);
close FH;
print ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n";
print "Check to result.txt\n";
print ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n";
sub find_use_file {
my $file = $_;
my $currentDir = getcwd;
if (-d $file) {
#print "skip dir : $file\n";
} elsif (-f $file) {
#print "file : $file\n";
if (/\b.9.png\b/i) {
print "search file : $File::Find::name\n";
# filename.png
my $lastindex = rindex($file, '.9');
my $search = substr($file, 0, $lastindex);
$currentDir = getcwd;
chdir('../..');
my $ret = system("find . -name -prune -o -type f \( -name '*.java' -o -name '*.xml' -o -name '*.c' \) -print0 | xargs -0 grep --color -n $search");
if($ret != 0) {
print FH $File::Find::name, "\n";
}
chdir($currentDir);
} elsif (/\b.png\b/i) {
print "search file : $File::Find::name\n";
# filename.png
my $lastindex = rindex($file, '.');
my $search = substr($file, 0, $lastindex);
$currentDir = getcwd;
chdir('../..');
my $ret = system("find . -name -prune -o -type f \( -name '*.java' -o -name '*.xml' -o -name '*.c' \) -print0 | xargs -0 grep --color -n $search");
if($ret != 0) {
print FH $File::Find::name, "\n";
}
chdir($currentDir);
} else {
#print "skip other file : $file\n";
}
}
}
TimerTask myTask = new TimerTask() {
public void run() {
// to do
}
};
Timer timer = new Timer();
//10 second
timer.schedule(myTask, 1000, 1000*10);
🎯 GPT-5와 Sora 2 API, 그리고 ChatGPT Apps: 오픈AI의 **AI 혁명** 핵심 정리! AI 혁명의 진짜 주인공은 이제야 등장했어요. GPT-4나 GPT-4o만 해도 엄청난 ...