2015-04-20 8 views
13

Sto provando a configurare Dagger nei test di strumentazione Espresso per prendere in giro le chiamate a risorse esterne (servizi RESTful in questo caso). Lo schema che ho seguito in Robolectric per il mio test unitario è stato quello di estendere la mia classe Application di produzione e sostituire i moduli di Dagger con i moduli di test che restituiranno i mock. Sto tentando di fare la stessa cosa qui, ma ricevo una ClassCastException nei miei test dell'Espresso quando tento di trasmettere l'applicazione alla mia applicazione personalizzata.Posso estendere un'applicazione personalizzata in Espresso?

Ecco il mio istituito finora:

Produzione

Sotto app/src// java/com/mypackage/iniezione principale che ho:

MyCustomApplication

package com.mypackage.injection; 

import android.app.Application; 

import java.util.ArrayList; 
import java.util.List; 

import dagger.ObjectGraph; 

public class MyCustomApplication extends Application { 

    protected ObjectGraph graph; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     graph = ObjectGraph.create(getModules().toArray()); 
    } 

    protected List<Object> getModules() { 
     List<Object> modules = new ArrayList<Object>(); 
     modules.add(new AndroidModule(this)); 
     modules.add(new RemoteResourcesModule(this)); 
     modules.add(new MyCustomModule()); 

     return modules; 
    } 

    public void inject(Object object) { 
     graph.inject(object); 
    } 
} 

Quale utilizzo nel modo seguente:

BaseActivity

package com.mypackage.injection.views; 

import android.app.Activity; 
import android.os.Bundle; 

import com.mypackage.injection.MyCustomApplication; 

public abstract class MyCustomBaseActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     ((MyCustomApplication)getApplication()).inject(this); 
    } 

} 

attività in prova

package com.mypackage.views.mydomain; 
// imports snipped for bevity 

public class MyActivity extends MyBaseActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //snip 
    } 
} 

Espresso Setup

Sotto app/src/androidTest/java/com/mypackage/iniezione che ho:

MyCustomEspressoApplication

package com.mypackage.injection; 

import java.util.ArrayList; 
import java.util.List; 

import dagger.ObjectGraph; 

public class MyCustomEspressoApplication extends MyCustomApplication { 

    private AndroidModule androidModule; 
    private MyCustomModule myCustomModule; 
    private EspressoRemoteResourcesModule espressoRemoteResourcesModule; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     graph = ObjectGraph.create(getModules().toArray()); 
    } 

    protected List<Object> getModules() { 
     List<Object> modules = new ArrayList<Object>(); 
     modules.add(getAndroidModule()); 
     modules.add(getEspressoRemoteResourcesModule()); 
     modules.add(getMyCustomModule()); 

     return modules; 
    } 

    public void inject(Object object) { 
     graph.inject(object); 
    } 

    public AndroidModule getAndroidModule() { 
     if (this.androidModule == null) { 
      this.androidModule = new AndroidModule(this); 
     } 

     return this.androidModule; 
    } 

    public MyCustomModule getMyCustomModule() { 
     if (this.myCustomModule == null) { 
      this.myCustomModule = new MyCustomModule(); 
     } 

     return this.myCustomModule; 
    } 

    public EspressoRemoteResourcesModule getEspressoRemoteResourcesModule() { 
     if (this.espressoRemoteResourcesModule == null) { 
      this.espressoRemoteResourcesModule = new EspressoRemoteResourcesModule(); 
     } 

     return this.espressoRemoteResourcesModule; 
    } 
} 

La mia prova Espresso, sotto app/src/androidTest/com/mypackage/espresso:

package com.mypackage.espresso; 

// imports snipped for brevity 

@RunWith(AndroidJUnit4.class) 
@LargeTest 
public class MyActivityTest extends ActivityInstrumentationTestCase2<MyActivity>{ 

    private MyActivity myActivity; 

    public MyActivityTest() { 
     super(MyActivity.class); 
    } 

    @Before 
    public void setUp() throws Exception { 
     super.setUp(); 
     injectInstrumentation(InstrumentationRegistry.getInstrumentation()); 
     myActivity = getActivity(); 
    } 

    @After 
    public void tearDown() throws Exception { 
     super.tearDown(); 
    } 

    @Test 
    public void testWhenTheActionBarButtonIsPressedThenThePlacesAreListed() { 
     //The next line is where the runtime exception occurs. 
     MyCustomEspressoApplication app = (MyCustomEspressoApplication)getInstrumentation().getTargetContext().getApplicationContext(); 
     //I've also tried getActivity().getApplication() and 
     // getActivity.getApplicationContext() with the same results 
     //snip 
    } 
} 

mio AndroidManifest.xml

(ho visto molte risposte riguardanti ClassCastException nelle classi di applicazioni personalizzate e molte di esse indicano una proprietà "android: name" mancante sul nodo Application. Sto incollando questo qui per dimostrare che questo non è il caso, per quanto posso dire)

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    package="com.mypackage"> 
    <!-- snip --> 
    <application 
     android:name=".injection.MyCustomApplication" 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
    <!-- snip --> 
    </application> 
<!-- snip --> 
</manifest> 

build.gradle

buildscript { 
    repositories { 
     mavenCentral() 
     jcenter() 
    } 
} 

apply plugin: 'com.android.application' 
apply plugin: 'idea' 

android { 
    testOptions { 
     unitTests.returnDefaultValues = true 
    } 
    lintOptions { 
     abortOnError false 
    } 
    packagingOptions { 
     exclude 'LICENSE.txt' 
     exclude 'META-INF/LICENSE' 
     exclude 'META-INF/LICENSE.txt' 
     exclude 'META-INF/NOTICE' 
    } 
    compileSdkVersion 21 
    buildToolsVersion "21.1.2" 

    defaultConfig { 
     applicationId "com.mypackage" 
     minSdkVersion 15 
     targetSdkVersion 21 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    } 
} 

idea { 
    module { 
     testOutputDir = file('build/test-classes/debug') 
    } 
} 

dependencies { 
    compile project(':swipeablecardview') 

    compile fileTree(dir: 'libs', include: ['*.jar']) 
    compile 'com.android.support:support-annotations:21.0.3' 
    compile 'com.android.support:appcompat-v7:21.0.3' 
    compile 'com.squareup:javawriter:2.5.0' 
    compile ('com.squareup.dagger:dagger:1.2.2') { 
     exclude module: 'javawriter' 
    } 
    compile ('com.squareup.dagger:dagger-compiler:1.2.2') { 
     exclude module: 'javawriter' 
    } 
    compile 'com.melnykov:floatingactionbutton:1.1.0' 
    compile 'com.android.support:cardview-v7:21.0.+' 
    compile 'com.android.support:recyclerview-v7:21.0.+' 
    // compile 'se.walkercrou:google-places-api-java:2.1.0' 
    compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1' 
    compile 'commons-io:commons-io:1.3.2' 
    testCompile 'org.hamcrest:hamcrest-integration:1.3' 
    testCompile 'org.hamcrest:hamcrest-core:1.3' 
    testCompile 'org.hamcrest:hamcrest-library:1.3' 
    testCompile('junit:junit:4.12') 
    testCompile 'org.mockito:mockito-core:1.+' 
    testCompile('org.robolectric:robolectric:3.0-SNAPSHOT') 
    testCompile('org.robolectric:shadows-support-v4:3.0-SNAPSHOT') 
    androidTestCompile 'org.mockito:mockito-core:1.+' 
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.0') { 
     exclude group: 'javax.inject' 
     exclude module: 'javawriter' 
    } 
    androidTestCompile('com.android.support.test:testing-support-lib:0.1') 
} 

Lo stacktrace:.

java.lang.ClassCastException: com.mypackage.injection.MyCustomApplication non può essere trasmesso a com.mypackage.injection.MyCustomEspressoApplication a com.mypackage.espresso.MyActivityTest.testWhenTheActionBarButtonIsPressedThenThePlacesAreListed (MyActivityTest.java:107) a java.lang.reflect.Method.invokeNative (metodo natale) a java.lang.reflect.Method.invoke (Method.java:511) a org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall (FrameworkMethod.java:45) a org.junit.internal.runners.model.ReflectiveCallable.run (ReflectiveCallable.java:15) a org.junit.runners.model.FrameworkMethod.invokeExplosively (FrameworkMethod.java: 42) a org.junit.internal.runners.statements.InvokeMethod.evaluate (InvokeMethod.java:20) a org.junit.internal.runners.statements.RunBefores.evaluate (RunBefores.java:28) a org.junit.internal.runners.statements.RunAfters.evaluate (RunAfters.java:30) a org.junit.runners.ParentRunner.runLeaf (ParentRunner.java:263) a org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:68) a org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:47) a org.junit.runners.ParentRunner $ 3.run (ParentRunner.java:231) a org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:60) a org.junit.runners.ParentRunner.runChildren (ParentRunner.java:229) a org.junit.runners.ParentRunner.access $ 000 (ParentRunner.java:50) a org.junit. runners.ParentRunner $ 2.evaluate (ParentRunner.java:222) a org.junit.runners.ParentRunner.run (ParentRunner.java:300) a org.junit.runners.Suite.runChild (Suite.java:128) presso org.junit.runners.Suite.runChild (Suite.java:24) a org.junit.runners.ParentRunner $ 3.run (ParentRunner.java:231) a org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:60) a org.junit.runners.ParentRunner.runChildren (ParentRunner.java:229) a org.junit.runners.ParentRunner.access $ 000 (ParentRunner .java: 50) a org.junit.runners.ParentRunner $ 2.valore (ParentRunner.java:222) a org.junit.runners.ParentRunner.run (ParentRunner.java:300) a org.junit.runner. JUnitCore.run (JUnitCore.java:157) a org.junit.runner.JUnitCore.run (JUnitCore.java:136) a android.support.test.runner.AndroidJUnitRunner.onStart (AndroidJUnitRunner.java:270) a android.app.Instrumentation $ InstrumentationThread.run (Instrumentation.java:1551)

Ho letto i documenti Espresso e Dagger e ho cercato senza problemi attraverso i problemi su Github. Apprezzerei qualsiasi aiuto che chiunque possa fornire. Grazie in anticipo.

Modifica # 1

ho seguito il suggerimento di Daniel di estendere il test runner e checkout la VerifyError, e ha ottenuto la seguente analisi dello stack:

java.lang.ExceptionInInitializerError 
      at org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:95) 
      at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57) 
      at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49) 
      at org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24) 
      at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33) 
      at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59) 
      at org.mockito.Mockito.mock(Mockito.java:1285) 
      at org.mockito.Mockito.mock(Mockito.java:1163) 
      at com.mypackage.injection.EspressoRemoteResourcesModule.<init>(EspressoRemoteResourcesModule.java:17) 
      at com.mypackage.injection.MyCustomEspressoApplication.getEspressoRemoteResourcesModule(MyCustomEspressoApplication.java:52) 
      at com.mypackage.injection.MyCustomEspressoApplication.getModules(MyCustomEspressoApplication.java:24) 
      at com.mypackage.injection.MyCustomApplication.onCreate(MyCustomApplication.java:18) 
      at com.mypackage.injection.MyCustomEspressoApplication.onCreate(MyCustomEspressoApplication.java:16) 
      at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:999) 
      at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4151) 
      at android.app.ActivityThread.access$1300(ActivityThread.java:130) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1255) 
      at android.os.Handler.dispatchMessage(Handler.java:99) 
      at android.os.Looper.loop(Looper.java:137) 
      at android.app.ActivityThread.main(ActivityThread.java:4745) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:511) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
      at dalvik.system.NativeStart.main(Native Method) 
    Caused by: java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils 
      at org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167) 
      at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) 
      at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217) 
      at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145) 
      at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117) 
      at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109) 
      at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105) 
      at org.mockito.cglib.proxy.Enhancer.<clinit>(Enhancer.java:70) 
            at org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:95) 
            at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57) 
            at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49) 
            at org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24) 
            at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33) 
            at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59) 
            at org.mockito.Mockito.mock(Mockito.java:1285) 
            at org.mockito.Mockito.mock(Mockito.java:1163) 
            at com.mypackage.injection.EspressoRemoteResourcesModule.<init>(EspressoRemoteResourcesModule.java:17) 
            at com.mypackage.injection.MyCustomEspressoApplication.getEspressoRemoteResourcesModule(MyCustomEspressoApplication.java:52) 
            at com.mypackage.injection.MyCustomEspressoApplication.getModules(MyCustomEspressoApplication.java:24) 
            at com.mypackage.injection.MyCustomApplication.onCreate(MyCustomApplication.java:18) 
            at com.mypackage.injection.MyCustomEspressoApplication.onCreate(MyCustomEspressoApplication.java:16) 
            at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:999) 
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4151) 
            at android.app.ActivityThread.access$1300(ActivityThread.java:130) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1255) 
            at android.os.Handler.dispatchMessage(Handler.java:99) 
            at android.os.Looper.loop(Looper.java:137) 
            at android.app.ActivityThread.main(ActivityThread.java:4745) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:511) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
            at dalvik.system.NativeStart.main(Native Method) 
04-29 06:40:28.594 1016-1016/? W/ActivityManager﹕ Error in app com.mypackage running instrumentation ComponentInfo{com.mypackage.test/com.mypackage.EspressoTestRunner}: 
04-29 06:40:28.594 1016-1016/? W/ActivityManager﹕ java.lang.VerifyError 
04-29 06:40:28.594 1016-1016/? W/ActivityManager﹕ java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils 

Questo mi indicò Mockito. Mi mancavano le librerie mockito e dexmaker necessarie.

ho aggiornato il mio dipendenze a:

androidTestCompile 'org.mockito:mockito-core:1.10.19' 
androidTestCompile 'com.google.dexmaker:dexmaker:1.2' 
androidTestCompile ('com.google.dexmaker:dexmaker-mockito:1.2') { 
    exclude module: 'hamcrest-core' 
    exclude module: 'mockito-core' 
} 
androidTestCompile('com.android.support.test.espresso:espresso-core:2.0') { 
    exclude group: 'javax.inject' 
} 

ho MyCustomModule anche overrode, che aveva bisogno di includere EspressoRemoteResourcesModule. Una volta che ho fatto queste cose ha iniziato a funzionare.

risposta

22

Con un canale di strumentazione personalizzato, è possibile ignorare newApplication e creare un'istanza diversa dall'applicazione predefinita dal manifest.

public class MyRunner extends AndroidJUnitRunner { 
    @Override 
    public Application newApplication(ClassLoader cl, String className, Context context) 
     throws Exception { 
    return super.newApplication(cl, MyCustomEspressoApplication.class.getName(), context); 
    } 
} 

Assicurarsi di aggiornare testInstrumentationRunner con il nome del corridore personalizzato.

+0

Provato questo, ora ho: Test su nexus_5_android_4_0_3 (AVD) - 4.1.1 non riuscito: esecuzione strumentazione non riuscita a causa di 'java.lang.VerifyError' : app: connectedAndroidTest FAILED com.android.builder.testing.ConnectedDevice> hasTests [nexus_5_android_4_0_3 (AVD) - 4.1 .1] [31mFAILED [0m Nessun test trovato. Questo sembra essere un nuovo terreno. C'è un altro metodo che ho bisogno di sovrascrivere per farlo rilevare i test? – jameskbride

+0

Puoi incollare l'intero 'VerifyError' (dovrebbe essere in logcat, credo) e qualsiasi avviso' dalvikvm'? 'Nessun test trovato di solito significa che c'è stato un errore durante l'installazione del corridore, prima dell'inizio dei test. –

+0

Vedere la mia modifica sopra. La versione TL; DR mi ha indirizzato nella giusta direzione estendendo il runner di test e esaminando VerifyError, che mi ha indirizzato verso Mockito e Dexmaker. Grazie per l'aiuto! – jameskbride

3

Non ho provato questo caso in tutti i casi, ma è possibile provare una regola personalizzata per specificare la propria classe di applicazione personalizzata per test case anziché per tutti i casi di test applicati dal runner personalizzato. Ho avuto successo con la seguente nei casi più semplici:

public class ApplicationTestRule<T extends Application> extends UiThreadTestRule { 
    Class<T> appClazz; 
    boolean wait = false; 
    T app; 

    public ApplicationTestRule(Class<T> applicationClazz) { 
     this(applicationClazz, false); 
    } 

    public ApplicationTestRule(Class<T> applicationClazz, boolean wait) { 
     this.appClazz = applicationClazz; 
     this.wait = wait; 
    } 

    @Override 
    public Statement apply(final Statement base, Description description) { 
     return new ApplicationStatement(super.apply(base, description)); 
    } 

    private void terminateApp() { 
     if (app != null) { 
      app.onTerminate(); 
     } 
    } 

    public void createApplication() throws IllegalAccessException, ClassNotFoundException, InstantiationException { 
     app = (T) InstrumentationRegistry.getInstrumentation().newApplication(this.getClass().getClassLoader(), appClazz.getName(), InstrumentationRegistry.getInstrumentation().getTargetContext()); 
     InstrumentationRegistry.getInstrumentation().callApplicationOnCreate(app); 
    } 

    private class ApplicationStatement extends Statement { 

     private final Statement mBase; 

     public ApplicationStatement(Statement base) { 
      mBase = base; 
     } 

     @Override 
     public void evaluate() throws Throwable { 
      try { 
       if (!wait) { 
        createApplication(); 
       } 
       mBase.evaluate(); 
      } finally { 
       terminateApp(); 
       app = null; 
      } 
     } 
    } 
} 

Poi, nel tuo caso di test, creare la regola:

@Rule 
public ApplicationTestRule<TestApplication> appRule = new ApplicationTestRule<>(TestApplication.class,true); 

Nota il secondo parametro è facoltativo. Se falso o lasciato fuori, l'applicazione personalizzata viene creata ogni volta prima di ogni caso di test. Se impostato su true, è necessario chiamare appRule.createApplication() prima della logica dell'applicazione.

+0

Si noti che ciò creerà l'applicazione, ma non impedisce alla classe dell'applicazione originale di avviarsi per prima. La risposta di Daniel sopra sostituisce l'attuale strumentazione runner, che consente di iniettare la tua classe di applicazioni simulate ogni volta che viene richiesta un'app, non solo durante le singole regole di test. – Joe

6

Mi ci è voluto un giorno intero per ottenere la risposta completa.

Fase 1: Override AndroidJUnitRunner

public class TestRunner extends AndroidJUnitRunner 
{ 
    @Override 
    public Application newApplication(ClassLoader cl, String className, Context context) 
      throws InstantiationException, IllegalAccessException, ClassNotFoundException { 
     return super.newApplication(cl, TestApplication.class.getName(), context); 
    } 
} 

Fase 2: sostituire l'AndroidJunitRunner esistente build.gradle

defaultConfig { 
    ... 
    // testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    testInstrumentationRunner 'com.xi_zz.androidtest.TestRunner' 
} 

Fase 3: Aggiungere com.android.support.test : runner to build.gradle

androidTestCompile 'com.android.support.test:runner:0.5' 
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' 

Fase 4: Solo se si ha questo errore

Warning:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (25.2.0) and test app (23.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details. 

Poi, aggiungere una riga:

androidTestCompile 'com.android.support:support-annotations:25.2.0' 
androidTestCompile 'com.android.support.test:runner:0.5' 
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' 

Infine, prova se funziona

@RunWith(AndroidJUnit4.class) 
public class MockApplicationTest 
{ 
    @Rule 
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class); 

    @Test 
    public void testApplicationName() throws Exception 
    { 
     assertEquals("TestApplication", mActivityRule.getActivity().getApplication().getClass().getSimpleName()); 
    } 
} 
+4

Mi hai salvato la giornata! Grazie.Ho riscontrato un errore "Test in esecuzione fallito: impossibile trovare le informazioni sulla strumentazione per: ComponentInfo {com.example.myapp.debug.test/android.support.test.runner.AndroidJUnitRunner}" anche se ho utilizzato un test runner personalizzato come suggerito . La soluzione è eliminare la configurazione ('android studio -> Esegui> Modifica configurazioni> Elimina tutto sotto Test di strumentazione Android'). Ora esegui nuovamente i test. – rpattabi

+0

@rpattabi Ho cancellato tutto ma ho avuto di nuovo errore :(e tutte le configurazioni sono tornate, cosa c'è di sbagliato in Android Studio! Provo a farlo con la console ma ho anche l'errore da lì. –