cocos2d-x(v3.14.1)のandroidで、sdkbox::PluginShare::init()時にクラッシュしてしまう
前提・実現したいこと
androidで、sdkboxのtwitterシェア機能(画像付き)を実装したいのですが、
android版のみ
sdkbox::PluginShare::init();
の部分でクラッシュしてしまいます。
iOSは問題なく動作しています。
発生している問題・エラーメッセージ
下記logcatを拾ったエラーメッセージになります。
twitter以外にもfabricのcrashlytics(answersは計測できている)もエラーを吐いており、
両方とも正しく動作していないようです。
```
E/CrashlyticsCore(13497): java.util.concurrent.ExecutionException: java.lang.NoSuchMethodError: io.fabric.sdk.android.services.common.Crash$FatalException.<init>
E/CrashlyticsCore(13497): at java.util.concurrent.FutureTask.report(FutureTask.java:94)
E/CrashlyticsCore(13497): at java.util.concurrent.FutureTask.get(FutureTask.java:174)
E/CrashlyticsCore(13497): at com.crashlytics.android.core.CrashlyticsExecutorServiceWrapper.executeSyncLoggingException(CrashlyticsExecutorServiceWrapper.java:44)
E/CrashlyticsCore(13497): at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler.uncaughtException(CrashlyticsUncaughtExceptionHandler.java:251)
E/CrashlyticsCore(13497): at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
E/CrashlyticsCore(13497): at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
E/CrashlyticsCore(13497): at dalvik.system.NativeStart.main(Native Method)
E/CrashlyticsCore(13497): Caused by: java.lang.NoSuchMethodError: io.fabric.sdk.android.services.common.Crash$FatalException.<init>
E/CrashlyticsCore(13497): at com.crashlytics.android.core.CrashlyticsCore.recordFatalExceptionEvent(CrashlyticsCore.java:715)
E/CrashlyticsCore(13497): at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler.writeFatal(CrashlyticsUncaughtExceptionHandler.java:808)
E/CrashlyticsCore(13497): at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler.handleUncaughtException(CrashlyticsUncaughtExceptionHandler.java:278)
E/CrashlyticsCore(13497): at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler.access$100(CrashlyticsUncaughtExceptionHandler.java:55)
E/CrashlyticsCore(13497): at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler$5.call(CrashlyticsUncaughtExceptionHandler.java:254)
E/CrashlyticsCore(13497): at com.crashlytics.android.core.CrashlyticsUncaughtExceptionHandler$5.call(CrashlyticsUncaughtExceptionHandler.java:251)
E/CrashlyticsCore(13497): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
E/CrashlyticsCore(13497): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
E/CrashlyticsCore(13497): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
E/CrashlyticsCore(13497): at io.fabric.sdk.android.services.common.ExecutorUtils$1$1.onRun(ExecutorUtils.java:75)
E/CrashlyticsCore(13497): at io.fabric.sdk.android.services.common.BackgroundPriorityRunnable.run(BackgroundPriorityRunnable.java:30)
E/CrashlyticsCore(13497): at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime(13497): FATAL EXCEPTION: main
E/AndroidRuntime(13497): java.lang.IllegalAccessError: tried to access method com.twitter.sdk.android.core.TwitterCore.<init>:(Lcom/twitter/sdk/android/core/TwitterAuthConfig;)V from class com.twitter.sdk.android.Twitter
E/AndroidRuntime(13497): at com.twitter.sdk.android.Twitter.<init>(Twitter.java:65)
E/AndroidRuntime(13497): at com.sdkbox.plugin.PluginShareTwitterConnector$1.run(PluginShareTwitterConnector.java:77)
E/AndroidRuntime(13497): at android.os.Handler.handleCallback(Handler.java:725)
E/AndroidRuntime(13497): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(13497): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(13497): at android.app.ActivityThread.main(ActivityThread.java:5159)
E/AndroidRuntime(13497): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(13497): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(13497): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:810)
E/AndroidRuntime(13497): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:577)
E/AndroidRuntime(13497): at dalvik.system.NativeStart.main(Native Method)
```
該当のソースコード
proj.android-studio/app/build.gradle
```
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion 23
buildToolsVersion "24"
defaultConfig {
applicationId "com.hogehogehogehoge"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0.0"
multiDexEnabled true
}
dexOptions {
incremental true
javaMaxHeapSize "4096M"
jumboMode = true
preDexLibraries = false
}
sourceSets.main {
java.srcDir "src"
res.srcDir "res"
jniLibs.srcDir "libs"
manifest.srcFile "AndroidManifest.xml"
assets.srcDir "assets"
}
signingConfigs {
release {
if (project.hasProperty("RELEASE_STORE_FILE")) {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_KEY_PASSWORD
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (project.hasProperty("RELEASE_STORE_FILE")) {
signingConfig signingConfigs.release
}
}
}
configurations {
all*.exclude group: 'com.android.support', module: 'support-annotations'
}
}
repositories {
mavenCentral()
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':libcocos2dx')
compile('com.twitter.sdk.android:twitter:+@aar') {
transitive = true; exclude module: 'support-v4'
}
compile ('com.facebook.android:audience-network-sdk:4.15.0'){
exclude group: 'com.google.android.gms';
}
compile('com.crashlytics.sdk.android:answers:1.3.10@aar') {
transitive = true; exclude module: 'fabric'
}
compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') {
transitive = true; exclude module: 'fabric'
}
//compile 'com.android.support:multidex:1.0.1'
compile 'com.google.firebase:firebase-core:10.0.1'
compile 'com.google.firebase:firebase-ads:10.0.1'
}
apply plugin: 'com.google.gms.google-services'
```
その他のbuild.gradleファイル
```
$ find ./ | grep build.gradle
.//cocos2d/cocos/platform/android/java/libs/gps/build.gradle
.//cocos2d/cocos/platform/android/libcocos2dx/build.gradle
.//cocos2d/cocos/platform/android/libcocos2dx/libs/facebook_lib/build.gradle
.//cocos2d/cocos/platform/android/libcocos2dx-with-controller/build.gradle
.//proj.android-studio/app/build.gradle
.//proj.android-studio/build.gradle
```
proj.android-studio/app/src/org/cocos2dx/cpp/AppActivity.java
```
package org.cocos2dx.cpp;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import org.cocos2dx.lib.Cocos2dxActivity;
import io.fabric.sdk.android.services.common.Crash;
import jp.hogehelper.ad.AdMob;
import jp.hogehelper.ad.Facebook;
import jp.hogehelper.ad.Nend;
import io.fabric.sdk.android.Fabric;
import com.crashlytics.android.answers.Answers;
import com.twitter.sdk.android.Twitter;
import com.twitter.sdk.android.core.TwitterAuthConfig;
import com.crashlytics.android.Crashlytics;
import com.google.firebase.analytics.FirebaseAnalytics;
import java.util.Locale;
public class AppActivity extends Cocos2dxActivity {
private FirebaseAnalytics mFirebaseAnalytics;
// Note: Your consumer key and secret should be obfuscated in your source code before shipping.
//private static final String TWITTER_KEY = "aaaaaaaaaa";
//private static final String TWITTER_SECRET = "bbbbbbbb";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY, TWITTER_SECRET);
Fabric.with(this, new Twitter(authConfig));
*/
Fabric.with(this, new Crashlytics());
Fabric.with(this, new Answers());
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
mFirebaseAnalytics.setAnalyticsCollectionEnabled(true);
}
@Override
protected void onResume() {
super.onResume();
AdMob.getInstance().onResume();
Facebook.getInstance().onResume();
Nend.getInstance().onResume();
AdMobVideo.getInstance().onResume();
} @Override
protected void onPause() {
AdMob.getInstance().onPause();
Facebook.getInstance().onPause();
Nend.getInstance().onPause();
AdMobVideo.getInstance().onPause();
super.onPause();
} @Override
protected void onDestroy() {
AdMob.getInstance().onDestroy();
//Facebook.getInstance().onDestroy();
Nend.getInstance().onDestroy();
AdMobVideo.getInstance().onDestroy();
super.onDestroy();
}
/**
* @return current language.
*/
public static String getCurrentLanguage() {
if (Locale.getDefault().getLanguage().equals("zh")) {
return Locale.getDefault().toString();
}
return Locale.getDefault().getLanguage();
}
/** * @return true if need reset review app state.
*/
public static boolean isNeedResetReviewAppState() {
try {
String currentAppVersion = Cocos2dxActivity.getContext().getPackageManager().getPackageInfo(Cocos2dxActivity.getContext().getPackageName(), 0).versionName;
String previousVersion = SharePrefs.getInstance().getAppVersion();
if (TextUtils.isEmpty(previousVersion)) {
// first launch
SharePrefs.getInstance().setAppVersion(currentAppVersion);
return true;
} else if (previousVersion.equals(currentAppVersion)){
// same version
}else{
// other version
SharePrefs.getInstance().setAppVersion(currentAppVersion);
return true;
}
return false;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}
}
```
proj.android-studio/app/src/org/cocos2dx/cpp/MultiDexHogeApplication.java
```
package org.cocos2dx.cpp;
import android.support.multidex.MultiDexApplication;
import com.applovin.sdk.AppLovinSdk;
import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;
import android.util.Log;
public class MultiDexHogeApplication extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
Log.d("tag_name", "soccerr ______debuglog text");
FacebookSdk.sdkInitialize(getApplicationContext());
AppEventsLogger.activateApp(this);
AppLovinSdk.initializeSdk(this);
SharePrefs.getInstance().init(this);
}
}
```
Class/AppDelegate.cpp
```
#include "AppDelegate.h"
#include "AppInitialize.hpp"
#include "SceneTop.hpp"
#include "SceneOpening.hpp"
#include <cocos2d.h>
#include "PluginGoogleAnalytics/PluginGoogleAnalytics.h" //sdkboxで入れたgoogleAnalytics
#include "PluginAdMob/PluginAdMob.h"
//#include "PluginFacebook/PluginFacebook.h"
#include <PluginShare/PluginShare.h>
//#include "PluginShare/PluginShare.h"
#include "AdMobHelper.hpp"
#include "AdMobManager.hpp" //admob周り全体を管理するもの
//#import <Firebase.h>
//#import <Answers/Answers.h>
//#import <Google/Analytics.h>
//#include "AdTest.hpp"
using namespace cocos2d;
AppDelegate::AppDelegate() {}
AppDelegate::~AppDelegate() {}
// if you want a different context,just modify the value of glContextAttrs
// it will takes effect on all platforms
void AppDelegate::initGLContextAttrs() {
// set OpenGL context attributions,now can only set six attributions:
// red,green,blue,alpha,depth,stencil
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
GLContextAttrs glContextAttrs = {5, 6, 5, 0, 16, 8};
#endif
GLView::setGLContextAttrs(glContextAttrs);
}
static int register_all_packages() {
return 0; // flag for packages manager
}
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if (!glview) {
glview = GLViewImpl::create("paz");
director->setOpenGLView(glview);
}
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);
// FPS表示 // turn on display FPS
// director->setDisplayStats(true);
// Set the design resolution
glview->setDesignResolutionSize(SCREEN_W, SCREEN_H,
ResolutionPolicy::EXACT_FIT);
register_all_packages();
// run
director->runWithScene(AppInitialize::create());
// share
//sdkbox::PluginShare::init();
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
// share
sdkbox::PluginShare::init();
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
// TODO androidだと落ちる
sdkbox::PluginShare::init();
#endif
// sdkbox: google analytics初期化
sdkbox::PluginGoogleAnalytics::init();
sdkbox::PluginGoogleAnalytics::startSession();
return true;
}
void AppDelegate::applicationDidEnterBackground() {
Director::getInstance()->stopAnimation();
// if you use SimpleAudioEngine, it must be pause
CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}
void AppDelegate::applicationWillEnterForeground() {
Director::getInstance()->startAnimation();
CocosDenshion::SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
```
試したこと
- google-play-services or supportv4周りの重複ライブラリを除去や、バージョン一致
- fabric(answers/crashlytics)との衝突回避
- とにかく、関係がありそうなライブラリを消したり足したり。汗
- sdkbox::PluginShare::init()一度も呼ばずに、sdkbox::PluginShare::share(info);をしても落ちはしない。
補足情報(言語/FW/ツール等のバージョンなど)
- cocos2d-x version3.14.1
- mac OSX 10.11.6
- xcode 8.21
- 計測&広告周りのSDKが沢山入っています。