Pyjnius: Herdar de classes Java não funciona

Criado em 22 ago. 2012  ·  7Comentários  ·  Fonte: kivy/pyjnius

Parte do problema é que JavaMetaClass. new assume que sempre será chamado para criar um proxy, quando será chamado para cada classe descendente. Na mesma linha, o manuseio do jclass_registry deve ser restrito aos proxies reais. Outra coisa que descobri é que o tratamento de objetos retornados de Java é negligente, o que impossibilita passá-los de volta para métodos Java.

Posso trabalhar em algumas dessas questões no devido tempo.

Gosto muito da rapidez com que o jnius carrega Java e pode usar as versões mais recentes do Python.

Quer apoiar esta questão? Poste uma recompensa por isso! Aceitamos recompensas via Bountysource .

enhancement

Todos 7 comentários

Desculpe a demora, você pode fornecer uma descrição mais específica (casos de teste?) para cada um desses problemas? Comecei alguns trabalhos para permitir a herança de classes java de python (usando proxies), mas não está completo, no entanto, os problemas que você aponta aqui parecem vagamente relacionados a isso e provavelmente devem ser divididos em vários problemas diferentes.

Desculpe entrar na discussão, mas herdar uma classe Java pode não ser o que você precisa @Apalala , acho que é uma ideia melhor envolver a classe Java em uma classe Python como é feito nesta classe . Pode não ser óbvio no código vinculado porque todas as autoclasses são feitas em java.py , mas o código é equivalente a

class MyJavaWrapperClass(AnyPythonClassOrMixin):

    def __init__(self, *args, **kwargs):
        JavaClass = autoclass('org.uber.cool.JavaClass`)
        self._my_java_object = JavaClass(*args, **kwargs)  # use double underscore to "hide" the Java object

As razões para não herdar a classe Java são:

  • Métodos Java usam convenções de nomenclatura Java e parecem feios no código Python, você provavelmente irá querer renomear os métodos para que eles tenham uma aparência Python e não surpreendam outros desenvolvedores acostumados com o pep8 (exceto se você fizer o antigo twisted e o antigo Zope código...)
  • Geralmente, evita desordenar o objeto python dict com métodos herdados de Java, alguns métodos Java não têm nada a ver em ligações Python, eles mal serão chamados talvez nunca. Agrupar a classe Java torna a classe Python mais limpa no REPL e possivelmente evita chamadas terríveis para métodos Java não suportados. Lembre-se do fato de que, se você não usar o sublinhado duplo, os métodos Java ainda estarão facilmente disponíveis.
  • Por último, mas não menos importante, há grandes chances de você ter que adicionar código clichê antes ou depois da chamada para alguns métodos Java, você provavelmente substituirá alguns métodos Java em Python para fazer a conversão apropriada de tipo/classe ou outras coisas , então você acaba criando um método Python para o método Java exatamente como faria quando envolve a classe Java em vez de herdá-la enquanto ainda é capaz de A) renomear o método B) manter o dict limpo. Veja os métodos de class Element , class Node e class Relationship no gráfico quase todos eles tem código clichê mesmo que na maioria das vezes seja para tornar a API mais Pythonica ;)

Do ponto de vista do desempenho, acho que não há impacto, mas @tshirtman pode saber melhor.

Outra coisa, envolver objetos Java funciona agora e muito bem :-)

É possível substituir o método java usando o código python por enquanto?
E a herança de classe java?

Passei muito tempo olhando para isso e cheguei à conclusão de que não havia uma maneira prática de fazer isso, além de gerar bytecode java em tempo de execução, existem bibliotecas para fazer isso, mas parecia adicionar muita complicação para a biblioteca, e provavelmente fora do escopo. Não tenho certeza sobre o fechamento, mas não acho que seja trabalhado, então não seria razoável marcá-lo como não corrigido.

@monami7001 algum progresso?

isso foi ~ 4 anos atrás e, que eu saiba, não, gerar bytecode java em tempo de execução ainda parece a única opção (e talvez não seja tão ruim quanto eu e devemos analisar isso).

Uma solução alternativa é:

  1. crie um projeto Java separado, incluindo o android.jar da API da versão do Android de destino
  2. implementar o código (herança/substituições...)
  3. exportar para jar
  4. importar no buildozer

para usá-lo com autoclass

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Hukuta picture Hukuta  ·  5Comentários

Thrameos picture Thrameos  ·  27Comentários

cthoyt picture cthoyt  ·  11Comentários

stania picture stania  ·  6Comentários

cmacdonald picture cmacdonald  ·  20Comentários