출처

https://developer.apple.com/library/content/technotes/tn2151/_index.html




Header

모든 crash 리포트들은 header 를 가지고 있다.

Incident Identifier: B6FD1E8E-B39F-430B-ADDE-FC3A45ED368C

CrashReporter Key: f04e68ec62d3c66057628c9ba9839e30d55937dc

Hardware Model: iPad6,8

Process: TheElements [303]

Path: /private/var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements

Identifier: com.example.apple-samplecode.TheElements

Version: 1.12

Code Type: ARM-64 (Native)

Role: Foreground

Parent Process: launchd [1]

Coalition: com.example.apple-samplecode.TheElements [402]

 

Date/Time: 2016-08-22 10:43:07.5806 -0700

Launch Time: 2016-08-22 10:43:01.0293 -0700

OS Version: iPhone OS 10.0 (14A5345a)

Report Version: 104 


Incident Identifier : 이 crash report 의 unique 한 식별자이다.

CrashReporter Key : 장치 별 식별자로, 동일한 장치의 두 보고서에는 동일한 값이 표현된다.

Beta Identifier : 장치와 공읍 업체의 조합에 대한 고유 식별자이다. Testlight 를 통해 배포된 앱에서만 노출된다.

Code Type : 장치의 아키텍쳐로 ARM-64, ARM, x86-64 또는 x86 중 하나이다.

Role : 앱 종료시 프로세스에 할당 된 task_role 을 뜻한다.





Exception Information

이 섹션에서는 충돌의 특성에 대한 정보를 제공하는
Mach Exception Type 및 관련 필드를 나열한다.
모든 crash report 에서 모든 입력란 (Exception Note, Exception Code ..)이 표시되지는 않는다.


처리되지 않은 Objective-C Exception 으로 인해 생성된 Crash Report

Exception Type: EXC_CRASH (SIGABRT)

Exception Codes: 0x0000000000000000, 0x0000000000000000

Exception Note: EXC_CORPSE_NOTIFY

Triggered by Thread: 0


Null 포인터에 값을 대입했기 때문에 생성된 Crash Report


Exception Type: EXC_BAD_ACCESS (SIGSEGV)

Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000

Termination Signal: Segmentation fault: 11

Termination Reason: Namespace SIGNAL, Code 0xb

Terminating Process: exc handler [0]

Triggered by Thread: 0



Exception Codes : 하나 이상의 64비트 16 진수로 인코딩 된 Exception 에 대한 프로세서 관련정보이다. 다른 필드에서 이를 이용하여 human-readable 한 정보를 추출한다.

Exception Subtype : human-readable 하게 바뀐 예외 코드의 이름

Exception Message : human-readable 하게 바뀐 예외 코드에서 추출한 추가 정보

Exception Note : Exceptoin Subtype 과 관련된 추가 정보로 이 필드에 SIMULATED 가 포함되어 있으면 Crash 는 아니지만 시스템 요청에 의해 종료된 것이다.

Termination Reason : 프로세스가 종료된 이유이다. 

Triggered by Thread : 예외가 발생한 Thread





Exception Type


Bad Memory Access [EXC_BAD_ACCESS // SIGSEGV // SIGBUS] 

프로세스가 유효하지 않은 메모리에 접근하려고 시도했거나
read-only memory 에 쓰기를 하려고하는 등의 memory protection level 에 허용하지 않는 방식으로
메모리에 접근하려고 했음을 의미한다.

Exceptoin Subtype 필드는 오류를 설명하는 kern_return_t 와 
액세스된 메모리 주소를 포함한다.

잘못된 메모리 액세스를 디버깅하기 위한 팁은 아래와 같다.

- objc_msgSend 또는 objc_release가 crash 난 thread backtrace 의 맨 위에 있으면 
프로세스가 할당 해제 된 객체를 메시지로 보내려고 시도했을 수 있다. 
이 crash 를 더 잘 이해하기 위해서는 Zommbie Instrument 를 이용해서 profiling 해보는 것이 좋다.

-  gpus_ReturnNotPermittedKillClient가 crash 난 thread backtrace 의 맨 위에 있으면 
백그라운드에서 OpenGL ES 또는 Metal로 렌더링을 시도했기 때문에 프로세스가 종료된 것이다. 
(https://developer.apple.com/library/content/qa/qa1766/_index.html) 를 참조하여 해결한다.

- Address Sanitizer (https://developer.apple.com/videos/play/wwdc2015/413/) 가 활성화 된 상태에서 앱을 실행한다.
Address Sanitizer 는 컴파일 된 코드에서 메모리 액세스와 관련된 추가 수단을 추가한다. 
Crash 가 발생할 수 있는 코드가 존재하면 xcode 에서 경고를 나타내준다.


Abnormal Exit [EXC_CRASH // SIGABRT] 

프로세스가 비정상적으로 종료되었을 때 나타나는 type 이다.
가장 일반적인 원인으로는 Objective-C/C++ 예외나 abort() 호출이 있다.

또한 App Extension 이 initialize 에 너무 많은 시간이 소요되어
워치독에 의해 종료된 경우 위 type 이 나타날 수 있다.

launch 시 정지로 인해 extension 이 kill 된 경우 crash report 의
Exception Subtype 은 LAUNCH_HANG 으로 노출된다.
Extension 에는 main function 이 없기 때문에 
initializing 에 오랜 시간이 걸리면 안된다.

initialzing 에 오랜 시간이 소요되지 않도록 오랜 시간이 걸리는 job 은 나중으로 미루는 것이 좋다.




Killed [SIGKILL]

시스템의 요청에 따라 프로세스가 종료되었음을 의미한다.
종료 원인을 더 잘 이해하려면 Termination Reason 필드를 확인해야한다.

아래는 Watch App 의 경우 나타날 수 있는 코드들이다.

0xc51bad01 : 백그라운드 작업을 수행하는 동안 너무 많은 CPU 시간을 사용했기 때문에 App 이 종료되었음을 나타낸다.
이 문제를 해결하려면 백그라운드 작업을 수행하는 코드를 보다 효율적으로 만들어 CPU 를 최적화하거나
백그라운드 작업량을 줄여야한다.

0xc51bad02 : 할당된 시간 내에 백그라운드 작업을 완료하지 못해 App 이 종료되었음을 나타낸다.
이 문제를 해결하려면 백그라운드 작업량을 줄여야한다.

0xc51bad03 : 할당 된 시간 내에 백그라운드 작업을 완료하지 못했음을 나타내고, 시스템이 백그라운드 작업을 수행하는데
많은 CPU 시간을 받지 못했을 정도로 전반적으로 바빴을 때 나타낸다.
앱이 백그라운드 작업에서 수행하는 작업량을 줄임으로써 문제를 피할 수는 있지만
앱 코드의 잘못이라기 보단 전체 시스템 로그로 인해 앱이 작업을 완료하지 못했을 가능성이 크다.



Quit [SIGQUIT]

App 의 lifttime 을 관리할 권한이 있는 다른 프로세스의 요청으로 종료되었음을 의미한다.

프로세스가 crash 난 것을 의미하지는 않지만 탐지 가능한 방식으로 오작동했을 가능성이 높다.


iOS 에서는 키보드 앱이 너무 오래 걸리면 키보드 앱이 종료된다.

crash report 에 표시된 Backtraces 가 담당 코드를 가리킬 가능성은 거의 없다.


이 이슈를 더 잘 이해하기 위해선 시작 중 작업의 대부분을 background thread 로 옮기거나

Extension 이 로드된 이후까지 지연시켜야한다.




Trace Trap [EXC_BREAKPOINT // SIGTRAP]

Abnormal Exit 에서 abort () 를 사용하는 것처럼
__builtin_trap() 을 사용했을 때 발생하는 Exception type 이다.

사용자가 디버깅을 위해 호출할 수 있다.
debugger 가 연결되어 있지 않다면 프로세스가 종료되고 crash report 가 생성된다.

하위 수준 라이브러리 (ex. libdispatch) 에서 치명적인 오류가 발생하면
해당 프로세스를 트랩한다.
오류에 대한 추가 정보는 crash report 의 추가 진단 정보 섹션이나 장치 콘솔에 있다.

Swift 코드는 런타임시 예기치 않은 조건이 발생하면 이 예외 유형으로 종료된다.

- Optional 타입이 아닌데 nil 값일 경우
- 강제 형 변환 실패

추가 정보가 장치의 콘솔에 기록되었을 수도 있기 때문에 
Backtraces를보고 예기치 않은 상황이 발생했는지 확인해야한다.

런타임 오류를 적절히 처리하려면 crash 위치의 코드를 수정해야한다. 
(ex. Optional 을 unwrapping 하는 대신 선택적 바인딩을 사용한다.)


Illegal Instruction [EXC_BAD_INSTRUCTION // SIGILL]

프로세스가 불법적이거나 정의되지 않은 명령을 실행하려고 시도했음을 의미한다. 
프로세스가 잘못 구성된 함수 포인터를 통해 잘못된 주소로 점프하려고 시도했을 수 있습니다.

Intel 프로세서에서 ud2 연산 코드는 EXC_BAD_INSTRUCTION 예외를 발생시키지만 
일반적으로 디버깅 목적으로 프로세스를 트랩하는 데 사용된다.

런타임시 예기치 않은 상황이 발생하면 Intel 프로세서의 Swift 코드가 종료시킨다.
자세한 내용은 Trace Trap (트레이스 트랩)을 참조한다.


Resource Limit [EXC_RESOURCE]

프로세스가 resource 소비 한도를 초과했음을 의미한다.
이것은 프로세스가 너무 많은 리소스를 사용하고 있다는 OS로부터의 알림이다. 
정확한 자원은 Exception Subtype 필드에 나열된다. 
Excpetion Note 필드에 NON-FATAL condition 이 포함되어 있으면 
crash report 는 있지만 앱이 종료되지 않았음을 알 수 있다.

Exception subtype 이 MEMORY 이면 앱 프로세스가 시스템에서 부과한 메모리 한계를 넘었음을 나타낸다.
Exception subtype 이 WAKEUPS 이면 프로세스의 스레드가 초당 너무 많이 깨어나고 있음을 의미하며 이는 CPU 를 자주 깨우고 배터리 수명을 소모할 수 있다.
일반적으로 이 에러는 잦은 스레드간 통신 (performSelector:onThread: or dispatch_async) 사용으로 인해 발생한다.


Guarded Resource Violation [EXC_GUARD]

프로세스가 보호된 리소스를 보호하지 않았음을 의미한다.


Other Exception Types

일부 crash report 에는 16 진수 값 (예 : 00000020)으로 이름이 지정되지 않은 예외 유형이 포함될 수 있다. 

이러한 오류 보고서 중 하나가 표시되면 예외 코드 필드를 직접 확인하여 자세한 내용을 확인해야한다.


0xbaaaaaad : Crash 보고서가 아닌 전체 시스템의 스택 샷임을 나타낸다. 스택 샷을 찍으려면 홈 버튼과 모든 볼륨 버튼을 누른다.

종종 이러한 로그는 사용자가 실수로 생성한 것이므로 오류를 나타내지는 않는다.


0xbad22222 : VoIP 앱이 너무 자주 다시 시작 되었기 때문에 iOS에 의해 종료되었음을 나타낸다.


0x8badf00d : watch dog 시간 초과가 발생하여 앱이 iOS 에 의해 종료되었음을 나타낸다. 

앱이 시스템 이벤트를 시작, 종료 또는 응답하는데 너무 오래 걸렸을 경우에 발생한다.

가장 많이 하는 실수로는 Main Thread 에서 synchronous 하게 네트워크 통신을 하는 경우가 있다.

MainThread 에서의 오래 걸리는 작업은 background thread 로 이동하거나 다르게 처리해 main thread block 을 막야아한다.


0xc00010ff : 발열(?) 로 인해 OS 에서 앱을 종료했음을 나타낸다.  이 것은 device 또는 환경에 의한 것일 수 있다.

App 을 보다 효율적으로 실행하기 위해 (https://developer.apple.com/videos/play/wwdc2011/312/) 를 참고한다.


0xdead10cc : 앱이 suspend 된 상태에서 파일 lock 또는 sqlite lock 을 유지했기 때문에 OS 에 의해 종료되었음을 나타낸다.

앱이 suspend 된 상태에서 파일이나 sqlite db 에서 작업을 수행하고 싶다면 

background job 을 등록하여 (beginBackgroundTask:) 해당 작업을 완료하고 잠금을 해제해야한다.

아래와 같이 에러가 발생되었다.

잘되던 빌드가 갑자기 안되면서 아래와 같은 에러가 떴다...

심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
오류  "ResolveLibraryProjectImports" 작업에서 예기치 않은 오류가 발생했습니다.
System.IO.FileNotFoundException: Could not load assembly 'MiGong, Version=0.0.0.0, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile?
파일 이름: 'MiGong.dll'
   위치: Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters)
   위치: Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(String fullName)
   위치: Xamarin.Android.Tasks.ResolveLibraryProjectImports.Extract(DirectoryAssemblyResolver res, ICollection`1 jars, ICollection`1 resolvedResourceDirectories, ICollection`1 resolvedAssetDirectories, ICollection`1 resolvedEnvironments)
   위치: Xamarin.Android.Tasks.ResolveLibraryProjectImports.Execute()
   위치: Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   위치: Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext() MiGong.Android   

이번에도 비쥬얼스튜디오를 껐다 켜면 되겠거니 했는데

그래도 계속 빌드오류가 발생되었다.;;

아 이건 또 먼가 ㅜㅠ

혹시나 해서 Android 쪽 프로젝트만 재빌드했다...

해결되었다;;;

앱을 배포했는데 12.0 버전에서 실행시 오류가 발생해서 반려?가되었다.

iOS 는 신규 버전이 나오면 거기까지 테스트를 해야하는구나;;;

그래도 다행인건 iOS xcode 버전을 올리고

윈도우에서 Visual Studio 를 실행하니 알아서 iOS 의 Xamarin.iOS 도 업데이트 해준다.

 

방법은 아래 링크에 자세히 나와있다.

https://docs.microsoft.com/ko-kr/xamarin/xamarin-forms/platform/wpf

 

주의할 점

1. 프레임워크 대상 버전이 4.7 이상이어야한다.

2. MainWindow.xaml 내용의 처음을 Window -> wpf:FormsApplicationPage 으로 변경해야한다.

3. MainWindow.xaml.cs 에서 상속을 FormsApplicationPage 으로 변경해야한다.

4. 링크에도 나와있듯이 WPF 프로젝트에 설치한 Xamarin.Forms 의 버전과 다른 프로젝트들과 버전을 맞춰야한다.

 

아래는 기본 자마린 솔루션에서 WPF 프로젝트만 추가한 내용이다.

XamarinStudy.z01

XamarinStudy.z02

XamarinStudy.zip

 

아래는 실행한 WPF 결과

 

WebView 에서 JavaScript 실행은 간단히 아래와 같히 펑션을 호출하면 된다.

this.webView.Eval("TestFunction()");

 

하지만 리턴이 있는 JavaSecript funtion 실행결과는 저 형태로는 안된다.

따로 Renderer 를 이용해 구현하는 방법을 소개한다.

 

먼저 .Net Standard 프로젝트에 아래와 같이 WebViewer 를 만든다.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Test
{
    public class WebViewer : WebView
    {
        public static BindableProperty EvaluateJavascriptProperty =
        BindableProperty.Create(nameof(EvaluateJavascript), typeof(Func<string, Task<string>>), typeof(WebViewer), null, BindingMode.OneWayToSource);

        public Func<string, Task<string>> EvaluateJavascript
        {
            get { return (Func<string, Task<string>>)GetValue(EvaluateJavascriptProperty); }
            set { SetValue(EvaluateJavascriptProperty, value); }
        }
    }
}

이제 위 항목을 상속받아서 각 기기별로 Renderer 를 생성하자.

 

Android

using System;
using System.Threading;
using System.Threading.Tasks;
using Android.Content;
using Android.Webkit;
using Test;
using Test.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.Droid
{
    public class WebViewRender : WebViewRenderer
    {
        public WebViewRender(Context context) : base(context)
        { }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement is WebViewer webView)
            {
                webView.EvaluateJavascript = async (js) =>
                {
                    var reset = new ManualResetEvent(false);
                    var response = string.Empty;
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Control?.EvaluateJavascript(js, new JavascriptCallback((r) => { response = r; reset.Set(); }));
                    });
                    await Task.Run(() => { reset.WaitOne(); });
                    return response;
                };
            }
        }
    }

    internal class JavascriptCallback : Java.Lang.Object, IValueCallback
    {
        public JavascriptCallback(Action<string> callback)
        {
            _callback = callback;
        }

        private Action<string> _callback;
        public void OnReceiveValue(Java.Lang.Object value)
        {
            _callback?.Invoke(Convert.ToString(value));
        }
    }
}

 

iOS

using System.Threading.Tasks;
using Test;
using Test.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.iOS
{
    public class WebViewRender : WebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.NewElement is WebViewer webView)
            {
                webView.EvaluateJavascript = (js) =>
                {
                    return Task.FromResult(this.EvaluateJavascript(js));
                };
            }
        }
    }
}

 

UWP

using System;
using Test;
using Test.UWP;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;

[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.UWP
{
    public class WebViewRender : WebViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement is WebViewer webView)
            {
                webView.EvaluateJavascript = async (js) =>
                {
                    return await Control.InvokeScriptAsync("eval", new[] { js });
                };
            }
        }
    }
}

 

이제 화면에서 아래와 같이 컨트롤을 넣고

<test:WebViewer x:Name="webView" HorizontalOptions="FillAndExpand"  VerticalOptions="FillAndExpand"/>

아래와 같이 코딩하면 function 의 결과 값을 받아올수 있다.

var result = await this.webView.EvaluateJavascript("GetTest();");

 

SMSConvey 어플을 좀 업그레이드 하려고 하는데 갑자기 아래와 같은 에러가 났다.

Detected problems with app native libraries(please consult log for details): libmonosgen-64bit-2.0.so: unauthorized access to "/system/lib64/libsqlite.so"

오레오 업데이트 하고 나서 에러가 발생된것 같은데

찾아보니 7.0 부터 발생한 내용이라고 하던데.. 일단 내가 7.0 일때 테스트 할때는 저런 에러가 발생되지 않았다.

SQLite 사용시 발생되는 에러로 해결방법은

Nuget 패키지 관리자에서 "sqlite-net" 을 제거하고 "sqlite-net-pcl" 을 설치하면 된다.

 

**추가 (아래 방식으로 완전히 해결됨)

아래와 같이 package 를 설치하고

 

아래 두파일을 삭제합니다.

 

 

참고

https://forums.xamarin.com/discussion/78234/android-libmonosgen-library-sqlite-problems-with-app-native-libraries

앱상에서 권한을 준항목들이

오레오 버전 부터는 몇몇 특정 권한들이 권한이 빠지고 다시 사용자에게 권한허용을 받아야합니다.

만약 오레오 이전 버전에 잘 동작하던게 오레오 버전에서 동작하지 않는다면

권한으로 인해 먼가 동작하지 않는지 의심해 봐야합니다.

아래는 Xamarin.Android 에서 권한을 체크하고 권한이 없는 항목에 대해서

권한 허용을 요청하는 코드입니다.

(제가 문제가 되었던 권한는 android.permission.READ_SMS,  android.permission.WRITE_EXTERNAL_STORAGE,android.permission.SEND_SMS 입니다.)

// 권한이 없어 권한허용을 물어볼 항목들
List<string> permissions = new List<string>();

// 권한이 있는지 확인할 항목들
List<string> checkPermissions = new List<string>();
checkPermissions.Add(Manifest.Permission.AccessNetworkState);
checkPermissions.Add(Manifest.Permission.Internet);
checkPermissions.Add(Manifest.Permission.WriteSms);
checkPermissions.Add(Manifest.Permission.BroadcastSms);
checkPermissions.Add(Manifest.Permission.BroadcastWapPush);
checkPermissions.Add(Manifest.Permission.ReceiveBootCompleted);
checkPermissions.Add(Manifest.Permission.ReceiveMms);
checkPermissions.Add(Manifest.Permission.ReceiveSms);
checkPermissions.Add(Manifest.Permission.SendSms);
checkPermissions.Add(Manifest.Permission.WriteExternalStorage);
checkPermissions.Add(Manifest.Permission.ReadSms);

// 권한이 있는지 확인하고 없다면 체크할 목록에 추가합니다.
foreach (var checkPermission in checkPermissions)
{
    if (ContextCompat.CheckSelfPermission(this, checkPermission) != (int)Permission.Granted)
    {
        permissions.Add(checkPermission);
    }
}

// 권한없는 항목에 대해서 추가 허용을 할지 물어보는 팝업을 띄웁니다.
ActivityCompat.RequestPermissions(this, permissions.ToArray(), 1);

위 코드를 추가하면 앱 실행시 아래처럼 허용을 묻는 팝업이 뜹니다.

 

없던 권한이 3가지 인데 알아서 권한을 묶을수 있는것 들은 묶어서 팝업이 뜨는것 같네요

다시 말하지만 기존에 AndroidManifest.xml 에 권한이 포함되있더라도

오레오버전부터는 문제가 되는 권한들이 있으므로 위 작업이 필요합니다.

 

참고

https://developer.android.com/about/versions/oreo/android-8.0-changes?hl=ko

 

심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
오류  /Users/mac/Library/Caches/Xamarin/mtbs/builds/MiGong.iOS/c10cbd8fd317519d3dd23b704514d419/bin/iPhone/Release/MiGong.iOS.app: errSecInternalComponent MiGong.iOS   

위과 같은 오류가 발생

mac 이 잠자기 모드이거나 로그인 활성화가 풀린경우 발생된다.

mac 으로 들어가 로그인하면 위 오류는 사라진다.

error MT1006: Could not install the application '/Users/mac/Library/Caches/Xamarin/mtbs/builds/MiGong.iOS/c10cbd8fd317519d3dd23b704514d419/bin/iPhone/Debug/MiGong.iOS.app' on the device 'Jun의 iPhone': AMDeviceSecureInstallApplicationBundle returned: 0xe8000087 (kAMDIncorrectArchitectureError).    0 

프로젝트 속성의 iOS 빌드 탭에서 지원되는 아키텍처를 ARM7+ARM64 으로 변경하면 오류가 해결된다.

 

 

심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
오류  Can't write [C:\Users\kjun\AppData\Local\Temp\tad3j0pm.d2m.jar] (Can't read [C:\Users\kjun\AppData\Local\Xamarin\Xamarin.GooglePlayServices.Base\25.0.0\embedded\classes.jar(;;;;;;!META-INF/MANIFEST.MF)] (Duplicate zip entry [classes.jar:com/google/android/gms/common/annotation/KeepName.class])) MiGong.Android D:\[01]Source\KJunDev\MiGong\MiGong\MiGong.Android\CREATEMULTIDEXMAINDEXCLASSLIST  

갑자기 위와같은 에러가 발생되었다. nuget 패키지를 이것 저것 깔다 먼가 충돌이 발생해 지웠는데

저런 에러가.;;;

구글링 하니 이런 저런 방법이 있었는데 난 아래 처럼 하니 해결되었다.

도구>Android>Android SDK Manager 클릭

 

도구 탭에서 Google Play services 를 체크 해제하여 변경 내용 적용 을 하고

다시 체크하여 변경 내용 적용을 하여 재설치를 진행한다.

이러니 에러가 해결되었다.

 

아래 다른 방법.
https://forums.xamarin.com/discussion/55601/in-a-xamarin-android-project-how-can-i-remove-warnings-duplicate-zip-entry-classes-jar

+ Recent posts