Imaginando se alguém tentou usar os novos recursos da linguagem Java 7 com o Android? Eu sei que o Android lê o bytecode que o Java cospe e o transforma em dex. Então, acho que minha pergunta é: ele pode entender o bytecode do Java 7?
188
Respostas:
Se você estiver usando Android estúdio , o Java 7 linguagem deve ser ativado automaticamente, sem quaisquer patches. A tentativa com recurso requer o nível 19+ da API e o material NIO 2.0 está ausente.
Se você não pode usar os recursos do Java 7, consulte a resposta do @Nuno sobre como editar o seu
build.gradle
.O seguinte é apenas para interesse histórico.
Uma pequena parte do Java 7 certamente pode ser usada com o Android (nota: testei apenas no 4.1).
Primeiro, você não pode usar o ADT do Eclipse porque é codificado permanentemente que apenas os compiladores Java 1.5 e 1.6 são compatíveis. Você pode recompilar o ADT, mas acho que não há uma maneira simples de fazer isso, além de recompilar todo o Android.
Mas você não precisa usar o Eclipse. Por exemplo, o Android Studio 0.3.2 , o IntelliJ IDEA CE e outros IDEs baseados em javac suportam a compilação no Android e você pode definir a conformidade até o Java 8 com:
Isso permite apenas os recursos da linguagem Java 7 e você dificilmente pode se beneficiar de algo, já que metade da melhoria também vem da biblioteca. Os recursos que você pode usar são aqueles que não dependem da biblioteca:
<>
)catch (Exc1 | Exc2 e)
)1_234_567
)0b1110111
)E esses recursos ainda não podem ser usados :
try
instrução -with-resources - porque requer a interface não existente "java.lang.AutoCloseable" (pode ser usada publicamente no 4.4+)... "yet" :) Acontece que, embora a biblioteca do Android esteja direcionada para a versão 1.6, a fonte do Android contém interfaces como AutoCloseable e interfaces tradicionais como Closeable herdam do AutoCloseable (embora SafeVarargs esteja realmente ausente). Nós poderíamos confirmar sua existência através da reflexão. Eles estão ocultos simplesmente porque o Javadoc possui a
@hide
tag, o que fez com que o "android.jar" não os incluísse.Já existe uma pergunta existente. Como faço para criar o SDK do Android com APIs ocultas e internas disponíveis? sobre como recuperar esses métodos. Você só precisa substituir a referência "android.jar" existente da plataforma atual pela nossa plataforma personalizada e, em seguida, muitas das APIs do Java 7 ficarão disponíveis (o procedimento é semelhante ao do Eclipse. Verifique Estrutura do projeto → SDKs).
Além do AutoCloseable, (apenas) os seguintes recursos da biblioteca Java 7 também são revelados:
Isso é basicamente tudo. Em particular, o NIO 2.0 não existe e o Arrays.asList ainda não é @SafeVarargs.
fonte
nio2
e outros brindes serão definitivamente uma boa notícia.AutoCloseable
interface não existe no tempo de execução do Android até o ICS (ou talvez até o HoneyComb). Portanto, mesmo se você usar o android.jar corrigido, receberáNoClassDefFoundError
no sistema 2.x.invokedynamic
que não é suportado pela JVM alvo Java 6.EDIT: No momento em que isso foi escrito, a versão mais recente era o Android 9 e o Eclipse Indigo. As coisas mudaram desde então.
Sim, eu tentei. Mas este não é um ótimo teste, pois a compatibilidade foi limitada ao nível 6 sem nenhuma maneira (pelo menos de maneira simples) de realmente usar o java 7:
Em seguida, instalei a versão mais recente do Android SDK (EDIT: Honeycomb, API13, no momento em que esta postagem foi escrita). Ele encontrou o meu JDK 7 e foi instalado corretamente. O mesmo para o ADT.
Mas tive uma surpresa ao tentar compilar e executar um aplicativo Hello Word para Android. A compatibilidade foi configurada para Java 6 sem nenhuma maneira de forçá-la para Java 7:
Então eu tive Olá mundo de trabalho, e também outros aplicativos, mais complicado e usando
SQLite
,Listview
,Sensor
eCamera
, mas isso só prova que a compatibilidade manipulação de Java 7 parece ser bem feito e trabalhar com Android.Então, alguém tentou com o bom e velho Ant, ignorar a limitação do Eclipse vista acima?
De qualquer forma, o SDK foi projetado para ser usado com Java 5 ou 6, conforme explicado aqui .
Podemos ter algo trabalhando com o Java 7, mas estaria funcionando "por acidente". A construção do DEX pode funcionar corretamente ou não e, uma vez que o DEX foi construído, ele pode funcionar ou não. Isso porque o uso de um JDK não qualificado fornece resultados imprevisíveis por definição.
Mesmo que alguém tenha criado com êxito um aplicativo Android no Java 7 comum, isso não qualifica o JDK. O mesmo processo aplicado a outro aplicativo pode falhar ou o aplicativo resultante pode ter erros vinculados ao uso desse JDK. Não recomendado.
Para aqueles que estão envolvidos no desenvolvimento de aplicativos da Web, isso é exatamente o mesmo que implantar um aplicativo da Web construído em Java 5 ou 6 em um servidor de aplicativos qualificado apenas para Java 4 (digamos, Weblogic 8, por exemplo). Isso pode funcionar, mas isso não é algo que pode ser recomendado para outros propósitos além de tentar.
fonte
Citação de dalvikvm.com:
Isso significa que o arquivo de origem .java não importa, é apenas o bytecode .class.
Até onde eu sei, apenas invokedynamic foi incluído no bytecode da JVM no Java 7, o restante é compatível com o Java 6. A linguagem Java em si não usa invokedynamic . Outros novos recursos, como a instrução switch usando String s ou a captura múltipla, são apenas açúcar sintático e não exigiram alterações no código de bytes. Por exemplo, a captura múltipla apenas copia a captura bloco de para cada exceção possível.
O único problema deve ser que as novas classes introduzidas no Java 7 estão ausentes no Android, como o AutoCloseable , por isso não tenho certeza se você pode usar a tentativa recurso -with-resources (alguém tentou?).
Algum comentário sobre isso? Estou esquecendo de algo?
fonte
No SDK do Android v15, juntamente com o Eclipse 3.7.1, o Java 7 não é suportado no desenvolvimento do Android. Definir a compatibilidade de origem como 1.7 determina a compatibilidade do arquivo .class gerado como 1.7, o que leva ao seguinte erro do compilador Android:
fonte
Para expandir a resposta acima por @KennyTM, se você estiver direcionando para a versão 4.0.3 e superior ( minSdkVersion = 15 ), use as APIs ocultas adicionando algumas classes ao android.jar do SDK do seu destino.
Depois de fazer isso, você pode usar try-with-resources em qualquer Closeable, além de implementar o AutoCloseable em suas próprias classes.
Fiz um zip contendo fontes e binários de todas as classes que precisavam ser modificadas no android.jar para disponibilizar essas APIs. Você só precisa descompactá-lo e adicionar os binários ao seu
android-sdk / platform / android-NN / android.jar
Você pode baixá-lo aqui: http://db.tt/kLxAYWbrTambém é importante notar que, nos últimos meses, Elliott Hughes fez alguns comprometimentos com a árvore do Android: finalizou o AutoCloseable , adicionou o SafeVarargs , exibiu várias APIs , corrigiu o construtor protegido da Throwable e adicionou suporte para os arquivos de classe da versão 51 no dx . Então, finalmente há algum progresso.
Editar (abril de 2014):
Com o lançamento do SDK 19, não é mais necessário corrigir o android.jar com as APIs adicionais.
O melhor método para usar a tentativa com recursos no Android Studio para um aplicativo direcionado para 4.0.3 e superior ( minSdkVersion = 15 ) é adicionar o seguinte
compileOptions
ao seubuild.gradle
:O Android Studio reclamará que a tentativa com recursos não pode ser usada com este nível da API, mas minha experiência é que sim. O projeto será desenvolvido e executado sem problemas em dispositivos com 4.0.3 e superior. Não tive problemas com isso, com um aplicativo que foi instalado em dispositivos com mais de 500k.
Para ignorar esse aviso, adicione o seguinte ao seu
lint.xml
:fonte
Parece que fazer isso funcionar com formiga pura é meio que um desdém.
Mas funcionou para mim: http://www.informit.com/articles/article.aspx?p=1966024
fonte
custom_rules.xml
, veja minha resposta aqui: stackoverflow.com/a/24608415/194894Para usar os recursos do Java 7 na criação de código pelo sistema de compilação baseado em formigas do Android, basta colocar o seguinte em seu
custom_rules.xml
diretório raiz do seu projeto:custom_rules.xml:
fonte
Algumas pessoas podem estar interessadas neste projeto git que encontrei, que parece permitir a execução do Java 7 no Android. https://github.com/yareally/Java7-on-Android
No entanto, é muito arriscado se eu adicionar isso no projeto atual em que trabalho. Então, esperarei até o Google oferecer suporte oficial ao Java 7.
fonte