Posted by MR 손
,
Posted by MR 손
,

2. 코루틴 사용법

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'

gradle에 코루틴을 추가했다면 아래와 같은 코드를 작성할 수 있다.

 

 
CoroutineScope(Dispatchers.쓰레드종류).동기/비동기 {
 
 
 
}

스레드의 종류는 총 3가지가 있다.

  • Main: 메인 스레드. 화면 UI 작업 등을 하는 곳
  • IO: 네트워크, DB 등 백그라운드에서 필요한 작업을 하는 곳
  • Default: 정렬이나 무거운 계산 작업 등을 하는 곳

동기/비동기는 이렇게 나타낸다.

  • lanuch: 동기
  • async: 비동기

 

 
CoroutineScope(Dispatchers.IO).async {
 
 
 
}

그럼 예를 들어 위 코드는?

네트워크 작업을 하는 스레드를 비동기로 돌린다는 소리다!

 

 
CoroutineScope(Dispatchers.Main).launch {
 
val html = CoroutineScope(Dispatchers.IO).async {
 
getHtml()
 
}.await()
 
 
 
textView.text = html.toString()
 
}

그럼 예를 들어 위 코드는?

동기식 메인 스레드 안에서

비동기식 IO스레드를 돌릴 건데

갑자기 await이 튀어나왔다. 이건 작업이 완료될 때까지 기다리겠다는 뜻이다.

작업이 완료되면 html에 값이 들어가고, 그걸 텍스트뷰에 뿌려주는 UI 작업을 하는 것이다.

 

 

 
액티비티{
 
CoroutineScope(Dispatchers.Main).launch {
 
val html = CoroutineScope(Dispatchers.Default).async {
 
getHtml()
 
}.await()
 
 
 
textView.text = html.toString() // 이거보다 밑에 토스트가 더 먼저 실행됨
 
}
 
 
 
Toast.makeText(this, "이게 먼저 뜨지롱", Toast.LENGTH_SHORT).show() // 다른 UI 작업
 
}

내가 이거 때문에 좀 많이 헷갈렸는데...

CoroutineScope 괄호 안에 있는 건 별도의 스레드라고 생각하면 된다.

즉, 괄호 안에서 겁~~~~나 늦게 작업이 진행된다고 해도

괄호 밖에서는 별도로 작업을 계속 진행한다는 소리다.

 

위 코드를 보면 코드의 순서에 따라

텍스트뷰가 토스트 메시지보다 먼저 바뀔 거 같지만

getHtml() 작업이 느려서 토스트 메시지가 먼저 뜬다.

 

이게 바로 코루틴을 이용한 비동기 실행이다.

더 자세하게 파고들면 새로운 개념, 새로운 함수들이 있는데

그건 다음 시간에 공부해야겠다..

 

3. 코루틴이 필요한 또 다른 예시 (딜레이 처리)

 
내부 DB 데이터를 삭제하는 코드() // 이게 느려서
 
recyclerView를 새로고침 하는 코드() // 이게 먼저 실행될 수 있다.

네트워크 작업과 달리 내부 DB를 이용하는 작업은 메인 스레드에서 할 수 있다.

이런 무거운 작업과 recyclerView를 메인 스레드에서 같이 사용하다 보면

나 같은 초보자는 문제를 직면하게 된다.

 

예를 들어, 내부 DB에 데이터가 많아서 삭제를 하는데 시간이 오래 걸린다고 치자.

코드상으로는 분명히 삭제를 하고 refresh를 했는데

화면에는 변화가 없는 것처럼, 삭제가 이루어지지 않은 것처럼 보이게 될 것이다.

실제로 로그를 찍어보면 새로고침이 먼저 되고 DB 삭제가 이루어진다.

 

 
내부 DB 데이터를 삭제하는 코드()
 
 
 
val handler = android.os.Handler()
 
handler.postDelayed({
 
recyclerView를 새로고침 하는 코드()
 
}, 1000)

이때 핸들러를 이용해서 해결하는 방법이 있다.

임의로 몇 초 늦췄다가 명령어를 실행하도록 하는 것이다.

단, 이 방법에는 단점이 있다.

 

  1. 항상 똑같은 시간만큼 기다려야 한다. 데이터량이 적으면 삭제를 빨리 끝내고 새로고침을 빨리 할 수 있는데도 불구하고 지정해둔 시간만큼 기다렸다가 다음 명령어를 실행해야 하는 것이다. 시간을 낭비하는 것이다.
  2. 데이터량이 많아져서 지정해둔 시간보다 더 오랜 시간이 걸리는 경우 다시 똑같은 문제가 발생한다. 핸들러가 의미가 없어지는 것이다. 삭제가 되기도 전에 다음 명령어가 실행돼버리는 그런 상황 말이다.

이러한 이유로 핸들러는 근본적인 해결책이 되지 못한다.

 

 
CoroutineScope(Dispatchers.Main).launch {
 
val temp = CoroutineScope(Dispatchers.Default).async {
 
내부 DB 데이터를 삭제하는 코드()
 
}.await()
 
 
 
recyclerView를 새로고침 하는 코드()
 
}

바로 이럴 때 코루틴을 사용하면 된다.

네트워크 작업이 아니니까 Dispatchers.IO가 아니라 Dispatchers.Default로 해주고..

비동기로 DB 작업을 하고, 기다렸다가 끝나면 바로 recyclerView를 새로고침 해주는 것이다.

 

이렇게 해서 오늘 공부한 내용은 끝!

 

 

출처 : https://jae-young.tistory.com/46

Posted by MR 손
,
Posted by MR 손
,


Privacy Policy

built the 카톡 단톡 잠수회원 찾기 app as a Free app. This SERVICE is provided by at no cost and is intended for use as is.

This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service.

If you choose to use my Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that I collect is used for providing and improving the Service. I will not use or share your information with anyone except as described in this Privacy Policy.

The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at 카톡 단톡 잠수회원 찾기 unless otherwise defined in this Privacy Policy.

Information Collection and Use

For a better experience, while using our Service, I may require you to provide us with certain personally identifiable information. The information that I request will be retained on your device and is not collected by me in any way.

The app does use third party services that may collect information used to identify you.

Link to privacy policy of third party service providers used by the app

Log Data

I want to inform you that whenever you use my Service, in a case of an error in the app I collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing my Service, the time and date of your use of the Service, and other statistics.

Cookies

Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory.

This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service.

Service Providers

I may employ third-party companies and individuals due to the following reasons:

  • To facilitate our Service;
  • To provide the Service on our behalf;
  • To perform Service-related services; or
  • To assist us in analyzing how our Service is used.

I want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.

Security

I value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and I cannot guarantee its absolute security.

Links to Other Sites

This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, I strongly advise you to review the Privacy Policy of these websites. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.

Children’s Privacy

These Services do not address anyone under the age of 13. I do not knowingly collect personally identifiable information from children under 13. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions.

Changes to This Privacy Policy

I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page.

Contact Us

If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at [App Contact informations].

This privacy policy page was created at privacypolicytemplate.net and modified/generated by App Privacy Policy Generator


Posted by MR 손
,

cen apk

카테고리 없음 2019. 7. 31. 16:32
Posted by MR 손
,






drawable/circle_progress.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" >
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="8"
android:useLevel="false">

<size
android:width="76dip"
android:height="76dip"/>
<gradient
android:angle="0"
android:endColor="@color/colorPrimary"
android:startColor="@android:color/transparent"
android:type="sweep"
android:useLevel="false"
/>
</shape>
</rotate>

사용법 layout에 아래와 같이 사용 하면 된다.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/base_content_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

</LinearLayout>

<LinearLayout
android:id="@+id/base_progressBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:clickable="true"
android:visibility="gone">

<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/circle_progress"
android:indeterminateDuration="1000"/>
</LinearLayout>

</FrameLayout>


Posted by MR 손
,

apktool

https://ibotpeaches.github.io/Apktool/

signApk

https://github.com/appium/sign



decomUtilPath="/devSohn/android_sdk/decompile/"    # 디컴파일 유틸들 있는 경로


1. APK 파일 디컴파일 하기 

apkPath="/user/xxx.apk"

# Step1. Decompile Start

java -jar ${decomUtilPath}apktool_2.3.4.jar d ${apkPath}



2. 디컴파일 된 APK > 재빌드 > Sign 하기

decompilePath="Step1에서 디컴파일 된 폴더 경로 "    # Step1에서 디컴파일 된 폴더 경로

decompileApkName="/Users/xxx/reCompile_$(date +"%Y-%m-%d_%H%M").apk"        # 디컴파일 빌드 APK

signedApkName="/Users/xxx/reCompile_$(date +"%Y-%m-%d_%H%M")_signed.apk"    # 서명완료된 APK

# Step2. ReCompile Apk Create

java -jar ${decomUtilPath}apktool_2.3.4.jar b ${decompilePath} -o ${decompileApkName}

# Step3. ReCompile Apk Signed

java -jar ${decomUtilPath}signapk.jar ${decomUtilPath}testkey.x509.pem ${decomUtilPath}testkey.pk8 ${decompileApkName} ${signedApkName}



빨간색 부분의 경로만 변경 해서 카피 후 실행 한다.


signapk.jar

testkey.pk8

testkey.x509.pem




Posted by MR 손
,