[Kotlin Logo]


안드로이드 뿐만 아니라 코드를 작성하다보면 보일러플레이트 코드가 생기기 마련이다.

예를들면 Java에서 Getter, Setter를 추가 한다던지, 안드로이드에서 findViewById를 사용한다던지..

반복되는 작업이지만 안할 수도 없는 것들이라 언제나 고민거리다. 하지만 나의 생각은 또 다른 누군가의 생각인 법!

이를 해결하기 위해 다양한 언어에서 다양한 방법이 나와있으니, 꼭 사용하여 반복되는 코드를 피할 수 있으면 피하는 것이 좋다.


안드로이드를 기준으로 Java에서는 Lombok과 ButterKnife의 어노테이션을 사용하여 위의 코드들을 제거할 수 있다.

코틀린에서는 data class와 kotlin android extensions(synthetic)를 사용하여 제거가 가능하다. (butterKnife -> kotterKnife도 있음)



이제 본론으로..예제

오늘은 코틀린에서 XML을 템플릿 처럼 사용하는 방법을 알아보려고 한다.

[toolbar의 title을 사용하지 않고 toolbar 내부에 textView를 넣어 textView의 값을 변경하는 예제]


1. toolbar.xml (템플릿처럼 사용 할 toolbar layout)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="4dp">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:minHeight="?attr/actionBarSize"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetRight="0dp"
app:contentInsetEnd="0dp" >

<TextView
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/toolbar_title"
android:textColor="@color/md_black_1000"
android:textSize="18sp"
android:textStyle="bold" />

</android.support.v7.widget.Toolbar>
</android.support.v7.widget.CardView>

2. MainActivity.kt

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.toolbar.*

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

toolbar_title.text = "제목이 들어갑니다."

}
}

3. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<include
android:id="@+id/topView"
layout="@layout/toolbar" />

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/topView">

</android.support.v7.widget.RecyclerView>
</RelativeLayout>


toolbar.xml을 만들어두고 사용할 화면에서 <include>를 해준 다음 Activity코드에서 toolbar.xml로 바로 접근이 가능하다.

toolbar의 설정을 변경하고 싶으면 toolbar.xxx , 내부에 textView를 변경하고 싶으면 toolbar_title.xxx 

물론 recyclerView도 바로 접근이 가능하여 recyclerView.xxx를 사용할 수 있다.

(일반적인 자바로 작성했었다면 findViewById ... toolbar ... recyclerView....... 이제 findViewById는 잊어도 된다.)


이와 비슷한 방법으로 Button을 만들어두고 Style을 지정하여 xml로 만들어두면 반복잡업 뿐만 아니라 다양한 어플리케이션에서도 활용할 수 있으니 얼마나 편한가!

또한 이러한 작업을 해두면 똑같은 버튼이라도 1px, 1dp가 다른 버튼이 생겨 전체의 틀이 망가지는 일을 없어 더욱 더 깔끔한 앱이 나올 것이다.


[Issue] "Unable to create Debug Bridge"


Dev&Prog/Android

Written by 블럭 on 2016. 4. 1. 19:06

Issue


Android Studio 2.1 Preview 4~5 를 설치 직후 다음과 같은 이슈가 발생하였다. 


Unable to create Debug Bridge: Unable to start adb server: Unable to obtain result of 'adb version'



Solution


1. 터미널에 접속하여 안드로이드가 설치 된 폴더 ( sdk - platform-tools )로 이동한다.

2. adb tcpip 5555를 입력한다. 

3. 안드로이드 스튜디오를 재시작한다. 

4. 정상적으로 작동된다.


참고한 주소 : http://stackoverflow.com/questions/33557845/android-studio-show-the-dialog-unable-to-create-debug-bridge-unable-to-start



아래 목록 중 한가지라도 해당이 된다면 이 포스팅의 내용이 해결책이 될 수 있음.

1. Fatal Signal 6 (SIGABRT) 
2. 
android INVOKE_INTERFACE || instr_code == Instruction::INVOKE_INTERFACE_RANGE Unexpected call into interface trampoline: invoke-virtual
3. ART Runtime ArrayIndexOutOfBoundsException
4. Retrofit을 사용중인 경우.

.........

이번 오류는 Retrofit과 gradle version으로 인한 것으로, Retrofit interface를 사용하여 rest통신을 실행할 때 예외가 발생하였다.
주 된 오류는 다음과 같다.

A/art: art/runtime/thread.cc:1344] Throwing new exception 'length=248; index=1273' with unexpected pending exception: java.lang.ArrayIndexOutOfBoundsException: length=248; index=1273

Check failed: count_ == 0 (count_=-1, 0=0) Attempted to destroy barrier with non zero count
A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 21705

위와 같은 오류가 발생한다면 다음의 사항을 의심해보아도 좋다.


1. Retrofit을 사용중이거나 최근에 버전을 업데이트 하였음.
2. Android Project Level의 Build.gradle 내용 중 com.android.tools.build:gradle:x.x.x 의 버전을 수정하였다.

해결책

from classpath 'com.android.tools.build:gradle:2.0.0-alpha8' to classpath 'com.android.tools.build:gradle:2.0.0-alpha3' // 2.0.0-alpha3 이하 버전으로 수정.


안드로이드를 개발하면서 많이 보게되는 deprecated.. 이전버전에서 지원하였지만 문제나 최신 API로 인하여 더 이상은 필요가 없는 경우에 이클립스에서 Notification 이런식으로 취소선을 쫙 그어준다.

이번에 처음으로 제대로 된 어플을 제작하는데 출시 마무리단계에서 좀 더 완벽해지고 싶은 마음에 눈에 거슬리는 노란색 느낌표들 모두를 제거하기 위해 deprecated를 제거해보았다.

이번 포스팅의 목표는 안드로이드 알림창인 Notification Class의 메소드인  Notification(icon, message, when)을 변경해보는 것이다.

기존 소스 코드
...(Context context, String message){
int icon = R.drawable.logo; 
long when = System.currentTimeMillis();
NotificationManager notificationManager =(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent nIntent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, nIntent, 0);
notification.setLatestEventInfo(context, title, message, pIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1234, notification);      
}


수정 소스 코드
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("제목")
.setContentText("내용")
.setSmallIcon(R.drawable.ic_angle)
.setTicker("상태바제목")
.setAutoCancel(true)
.build();
notificationManager.notify(1234, notification);

두 코드의 메소드가 있고 없고 차이는 상관없음. ( 알림 하나 만들어두려면 수정 코드 처럼 정의해두고 Push처럼 Message를 전송하려면 메소드 정의해서 호출 후 notify하는 식으로 ...)

기존 코드에서는 Notification을 생성하며 정의 된 icon, message, when을 넣은 반면,
수정 코드에서는 Notification Builder를 이용하여 필요한 설정을 넣어주는 식이다.딱 봐도 훨씬 간결하고 수정하기 쉬워 보인다.


참조 
Notification - http://developer.android.com/reference/android/app/Notification.html
Intent - http://developer.android.com/reference/android/content/Intent.html
Context http://developer.android.com/reference/android/content/Context.html


안드로이드 내장 DB 접근


Dev&Prog/Android

Written by 블럭 on 2013. 12. 24. 17:09

cmd -> adb shell -> su -> 권한획득 확인 -> chmod 777 /data -> DDMS data 폴더 접근

1시간동안 삽질했는데 결론은 루팅 된 폰에서만 접근 가능한 것 같다..............
내장 DB 배워보려고 했는데 초반부터 시간만 잡아먹었다.

안드로이드 로그인


Dev&Prog/Android

Written by 블럭 on 2013. 2. 24. 00:02

  requestWindowFeature(Window.FEATURE_NO_TITLE);

없애고자 하는 Layout의 Activity중 Oncreate 매서드 부분에 윗 구문을 집어넣으면 된다

또한 전체화면을 원할경우 아래 내용을 manifest에 추가한다.

android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >