Um resumo das perguntas de entrevista comuns do Android supercompletas reunidas em quase quarenta entrevistas

Este artigo classifica cerca de 40 perguntas de entrevistas de amigos ao meu redor e adiciona meu próprio entendimento e alguns comentários maravilhosos ao artigo. Todos os artigos não são originais

Questões de entrevista:

1. Fale sobre o processo de customização do LayoutManager?

  • Determinar o LayoutParamsgenerateDefaultLayoutParams do Itemview
  • Determine a posição de todas as visualizações de item na visualização de reciclagem e recicle e reutilize a visualização de item emLayoutChildren
  • Adicionar lata deslizanteScrollVerticalmente

2. O que é RemoteViews? Quais são os cenários de uso?

RemoteViews é traduzido como visão remota.Como o nome sugere, RemoteViews não é a visão do processo atual, mas pertence ao processo SystemServer.O aplicativo e RemoteViews dependem do Binder para realizar a comunicação entre processos.

Uso: geralmente na barra de notificação

//1.创建RemoteViews实例
RemoteViews mRemoteViews=new
RemoteViews("com.example.remoteviewdemo", R.layout.remoteview_layout);
//2.构建一个打开Activity的PendingIntent Intent
intent=new
Intent(MainActivity.this,MainActivity.class);
PendingIntent
mPendingIntent=PendingIntent.getActivity(Main
Activity.this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
//3.创建一个Notification
mNotification = new
Notification.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(mPendingIntent)
.setContent(mRemoteViews)
.build();
//4. 获 取 NotificationManager
manager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE
);
Button button1 = (Button)
findViewById(R.id.button1);
button1.setOnClickListener(new
OnClickListener() {
@Override
public void onClick(View v) {
//弹出通知
manager.notify(1, mNotification);
}
});

3. Fale sobre várias maneiras de obter a largura e a altura da visualização?

  • OnGlobalLayoutListener obtém
  • OnPreDrawListener obtém
  • OnLayoutChangeListener obtém
  • Reescrever o onSizeChanged() da View
  • Use o método View.post()

4. Fale sobre interpoladores e estimadores?

  • Um interpolador que calcula
    a porcentagem de alteração de uma propriedade com base na porcentagem de tempo (tempos de animação) decorrido. Por padrão, existem interpoladores de velocidade constante, aceleração e desaceleração e desaceleração.
  • O estimador, que calcula
    o valor da variação específica através do percentual obtido pelo interpolador acima. Os padrões do sistema são inteiros, ponto flutuante e estimadores de cores
  • As personalizações só precisam substituir seu método de avaliação.

5. Qual é a diferença entre getDimension, getDimensionPixelOffset e getDimensionPixelSize?

O mesmo ponto: quando a unidade for dp/sp, será multiplicada pela densidade, e se a unidade for px, não será multiplicada

diferença:

  • getDimension retorna um valor float
  • getDimensionPixelSize, retorna um valor int, ao converter float para int, arredondar para cima
  • getDimensionPixelOffset, retorna um valor int, ao converter float para int, arredonda para baixo (ou seja, ignora valores decimais)

6. Em relação ao LayoutInflater, como ele obtém uma View específica através do método inflate?

O sistema cria um construtor de layout através de LayoutInflater.from. No método inflate, ele finalmente usará createViewFromTag. Aqui ele julgará os dois parâmetros fábrica2 e fábrica. Se ambos estiverem vazios, o sistema criará uma visão por si só e por meio de um xml, obtenha o nome do rótulo e, em seguida, julgue se é <Button ou xxx.xxx.xxView. Em seguida, vá para createView para obter o caminho completo do nome da classe por meio de splicing e crie uma classe por reflexão.

7. Fale sobre o mecanismo de cache do RecyclerView?

scrap viewCacherecyclerPool:
scrap é o cache atualmente exibido, e o viewCache em cache é um cache invisível fora da tela durante o onlayout. Você pode definir o viewCache para ser maior e alterar o espaço para o tempo para evitar deslizamento rápido dentro de uma certa distância. O acima dois caches não usam createView e onbind recyclerPool é especial. Ele ficará onbind. Ele pode ser compartilhado por vários recyclerViews. O uso real é: compartilhar itens entre vários recyclerViews, aplicar recyclerView horizontal incorporado em recyclerView vertical ou vários recyclerViews em viewpager

8. Fale sobre a diferença entre View.inflate e LayoutInflater.inflate?

praticamente nenhuma diferença

  • View.inflate é na verdade uma camada de embalagem para LayoutInflater.inflate.Funcionalmente, LayoutInflate é mais poderoso.
  • View.inflate finalmente chama o método de LayoutInflater.inflate(@LayoutRes int resource, @nullable ViewGroup root) com três parâmetros. Se a raiz passada aqui não estiver vazia, a View analisada será adicionada a este Go entre o ViewGroup.
  • O método LayoutInflater.inflate pode especificar se a View atual precisa ser adicionada ao ViewGroup

9. Fale sobre a diferença e os cenários de aplicação entre os métodos invalidate() e postInvalidate()?

  • invalidate() é usado para redesenhar a interface do usuário e precisa ser chamado no thread da interface do usuário.
  • postInvalidate() também é usado para redesenhar a interface do usuário. Ele pode ser chamado no thread da interface do usuário ou em um subthread. O método postInvalidate() envia uma mensagem por meio do manipulador para alternar o thread de volta para o thread da interface do usuário para notificar o redesenho , para não dizer que postInvalidate() pode atualizar a IU no encadeamento filho, basicamente o redesenho ocorre no encadeamento da IU, mas usamos postInvalidate() que nos ajudará a alternar os encadeamentos internamente

10. Fale sobre os cenários de uso e uso de SurfaceView e TextureView?

  • Desenho frequente e requisitos de alta taxa de quadros, como tirar fotos, vídeos e jogos, etc.
  • O SurfaceView possui uma superfície de desenho independente, que pode ser desenhada em sub-threads.
    A desvantagem é que ele não pode executar operações de translação, dimensionamento, rotação e gradiente transparente. O surgimento do TextureView é para resolver esses problemas
  • O uso do SurfaceView é provavelmente para obter o objeto SurfaceHolder, monitorar a criação, atualização, destruição da superfície, criar um novo thread e desenhá-lo e enviá-lo nele
  • O TextureView não possui uma superfície de desenho independente. Durante o uso, você precisa adicionar um monitor para ver se o surfaceTexture está disponível e, em seguida, fazer o processamento correspondente

11. Fale sobre a diferença entre vários métodos de atualização do RecyclerView.Adapter?

Atualiza todos os itens visíveis, notifyDataSetChanged() atualiza o item especificado, notifyItemChanged(int)
atualiza o item especificado da posição especificada, notifyItemRangeChanged(int,int) insere, move um e atualiza automaticamente, notifyItemInserted(int), notifyItemMoved(int), notifyItemRemoved(int) atualização parcial, notifyItemChanged(int, Object)

12. Você já ouviu falar sobre WindowInsets? Quais são suas aplicações?

ViewRootImpl chamará dispatchApplyInsets ao executar Traversals e chamará internamente DecorViewdispatchApplyWindowInsets para distribuir WindowInsets.

Treze, fale sobre o mecanismo de atualização da tela?

Frequência de atualização de tela e frequência de desenho cpu é responsável por measurelayoutdraw => displayList gpu é responsável por display => bitmap enviará um sinal de sincronização vertical a cada 16 ms e vsync retirará o bitmap renderizado do buffer gpu toda vez que o sinal for enviado e exibi-lo na tela Ao mesmo tempo, se necessário, o próximo cálculo da CPU será executado e o cálculo será colocado no buffer. Se o tempo de cálculo exceder o tempo entre dois vsyncs, ou seja, 16ms, o sinal vsync vai colocar o buffer gpu anterior Quando a informação for exibida, ela fica travada neste momento. Além disso, se a página não mudar, a tela ainda irá para o buffer para tirar a última atualização, mas a CPU não funcionará mais calculá-lo.

14. Quais são as formas de usar multithreading em Java?

Existem aproximadamente quatro tipos:
extends Thread; implRunnable; implCallable cria threads através do wrapper FutureTask; usa ExecutorService, Callable e Future para implementar multi-threading com resultados de retorno. ;Threads que estendem Thread e implRunnable não têm valor de retorno, enquanto FutureTask ExecutorService(ExecutorService.submit(xxx) return Future<?> ) tem um valor de retorno

15. Conte-me sobre vários estados de threads?

A primeira é criar estado. Quando o objeto thread é gerado, o método start do objeto não é chamado, o que significa que o thread está no estado criado.

O segundo é o estado pronto. Quando o método start do objeto de encadeamento é chamado, o encadeamento entra no estado pronto, mas neste momento o agendador de encadeamento não definiu o encadeamento como o encadeamento atual, portanto, está no estado pronto. Depois que o thread for executado, depois de retornar da espera ou da suspensão, ele também estará no estado pronto.

O terceiro é o status de execução. O agendador de encadeamento define o encadeamento no estado pronto como o encadeamento atual. Nesse momento, o encadeamento entra no estado de execução e começa a executar o código na função de execução.

O quarto é o estado de bloqueio. Quando um thread está em execução, ele é suspenso, geralmente para aguardar um certo tempo (por exemplo, um recurso está pronto) antes de continuar a execução. Suspensão, suspensão, espera e outros métodos podem causar bloqueio de thread.

O quinto é o estado de morte. Se o método run de um thread terminar ou o método stop for chamado, o thread morrerá. Para um thread morto, o método start não pode mais ser usado para torná-lo pronto.

16. Como conseguir sincronização em multithreading?

Multithreading síncrono e assíncrono não são a mesma coisa. Várias situações,
1. É o que todos chamam de sincronizado, o que pode garantir a atomicidade e garantir que apenas um encadeamento possa manter o bloqueio quando vários encadeamentos operam o mesmo método e operam este método. 2. Chame manualmente o bloqueio de leitura e gravação
3
. Manualmente A espera e notificação do thread operacional
4. volátil que eu lembro não é atômico, pode garantir a visibilidade da memória e, no caso de multi-threading, garantir que os dados de cada thread estejam atualizados

Dezessete, a definição de impasse

Multithreading e multiprocessamento melhoram a utilização dos recursos do sistema e aumentam a capacidade de processamento do sistema. No entanto, a execução simultânea também traz um novo problema - impasse. O chamado impasse refere-se a um impasse (esperando um pelo outro) causado por várias threads competindo por recursos.Se não houver força externa, esses processos não conseguirão avançar.

Dezoito, a causa do impasse

  1. Competição por recursos do sistema 2. A sequência de avanço do processo não é 3. O uso indevido de semáforos também pode causar deadlocks.

Dezenove, as condições necessárias para o impasse

Condições mutuamente exclusivas: O processo requer controle exclusivo sobre os recursos alocados (como impressoras), ou seja, um recurso é ocupado por apenas um processo dentro de um período de tempo.
Neste momento, se outros processos solicitarem o recurso, o processo solicitante poderá apenas aguardar.

Condição de não privação: O recurso obtido pelo processo não pode ser retirado forçosamente por outros processos antes de ser esgotado, ou seja, só pode ser liberado pelo próprio processo que obteve o recurso (somente liberação ativa).

Condições de solicitação e retenção: O processo reteve pelo menos um recurso, mas propõe uma nova solicitação de recurso, e o recurso já está ocupado por outros processos. Neste momento, o processo solicitante é bloqueado, mas não libera o recursos que obteve.

Condição de espera circular: Existe uma cadeia de espera circular de recursos do processo, e o recurso obtido por cada processo na cadeia é solicitado simultaneamente pelo próximo processo na cadeia.

20. A eficiência do hardware

É impossível para um processador de computador lidar com a maioria das tarefas em execução contando apenas com o "cálculo" do processador. O processador precisa interagir pelo menos com a memória, como ler dados de cálculo e armazenar resultados de cálculo. O funcionamento é difícil de eliminar (é impossível completar todas as tarefas de cálculo apenas com registradores).
Como há uma lacuna de várias ordens de magnitude entre a velocidade de computação do dispositivo de armazenamento do computador e o processador, a fim de evitar que o processador espere a conclusão das lentas operações de leitura e gravação da memória, os sistemas de computador
modernos e velocidade de gravação o mais próximo possível da velocidade de computação do processador . O cache atua como um buffer entre a memória e o processador: copie
os dados necessários para a operação no cache, para que a operação possa ser executada rapidamente e, em seguida, sincronize do cache de volta para a memória após a conclusão da operação.

21. Problema de consistência de cache

A interação do sistema de armazenamento baseado em cache resolve bem a contradição entre a velocidade do processador e da memória, mas também traz maior complexidade ao sistema do computador, pois introduz
um novo problema: a coerência do cache.
Em um sistema multiprocessador (ou um sistema multi-core de processador único), cada processador (cada núcleo) possui seu próprio cache e eles compartilham a mesma memória principal (Memória principal). Quando as tarefas de cálculo de vários processadores envolvem a mesma área de memória principal, isso pode causar inconsistência em seus respectivos dados de cache. Para isso, cada processador precisa seguir alguns protocolos ao acessar o cache, e operar de acordo com o protocolo na leitura e escrita para manter a consistência do cache.

22. Problema de otimização de execução fora de ordem de código

Para fazer uso total das unidades de computação dentro do processador e melhorar a eficiência da computação, o processador pode executar o código de entrada fora de ordem, e o processador reorganizará os
resultados da execução fora de ordem após o cálculo. A otimização de ordem pode garantir que o resultado da execução em um único thread seja consistente com o resultado da execução sequencial, mas não garante que a
ordem de cálculo de cada instrução no programa seja consistente com a ordem no código de entrada.

Vinte e três, a composição do modelo de memória Java

Memória principal: O modelo de memória Java estipula que todas as variáveis ​​sejam armazenadas na memória principal (Memória Principal).

Memória de trabalho: Cada thread possui sua própria memória de trabalho (Memória de Trabalho, também conhecida como memória local, que pode ser comparada com o cache do processador apresentado anteriormente), e a memória de trabalho da thread armazena as variáveis ​​usadas pela thread na memória principal Uma cópia da variável compartilhada. A memória de trabalho é uma abstração do JMM e realmente não existe. Abrange caches, buffers de gravação, registros e outras otimizações de hardware e compilador.

24. Problemas de simultaneidade das operações de memória da JVM

1. Consistência dos dados da memória de trabalho Quando cada thread operar dados, ela salvará a cópia da variável compartilhada na memória principal utilizada. Quando as tarefas de cálculo de várias threads envolverem a mesma variável compartilhada, as respectivas cópias da variável compartilhada serão inconsistente. Se isso acontecer, os dados de cópia de quem prevalecerão quando os dados forem sincronizados de volta à memória principal? O modelo de memória Java garante principalmente a consistência dos dados por meio de uma série de protocolos e regras de sincronização de dados, que serão apresentados em detalhes posteriormente.

2. Otimização da reordenação de instruções Em Java, a reordenação geralmente é um método para reordenar e executar instruções adotadas pelo compilador ou ambiente de tempo de execução para otimizar o desempenho do programa. Existem dois tipos de reordenação: reordenação em tempo de compilação e reordenação em tempo de execução, correspondendo a ambientes de tempo de compilação e de tempo de execução, respectivamente. Da mesma forma, a reordenação de instruções não é uma reordenação aleatória. Ela precisa atender às duas condições a seguir:
1) O resultado da execução do programa não pode ser alterado em um ambiente de thread único. O compilador just-in-time (e processador) precisa garantir que o programa pode estar em conformidade com os atributos as-if-serial. Em termos leigos, é dar ao programa uma ilusão de execução sequencial no caso de thread único. Ou seja, os resultados da execução reordenada devem ser consistentes com os resultados da execução sequencial.
2) A reordenação não é permitida se houver dependência de dados. Em um ambiente multi-threaded, se houver uma dependência entre a lógica de processamento de threads, o resultado da execução pode ser diferente do resultado esperado devido à reordenação das instruções. Posteriormente, podemos irá expandir como o modelo de memória Java resolve este problema.

Vinte e cinco, fale sobre o ciclo de vida da atividade?

Em circunstâncias normais, o ciclo de vida comum da Atividade é apenas o seguinte 7

  • onCreate(): indica que a atividade está sendo criada e é frequentemente usada para inicializar o trabalho, como chamar setContentView para carregar recursos de layout de interface, inicializar os dados necessários para a atividade, etc.;
  • onRestart(): Indica que a atividade está reiniciando.Em circunstâncias normais, OnRestart será chamado quando a atividade atual mudar de invisível para visível novamente;
  • onStart(): Indica que a Activity está sendo iniciada. Neste momento, a Activity está visível, mas não em primeiro plano. Ela ainda está em segundo plano e não pode interagir com o usuário;
  • onResume(): Indica que a Activity ganhou foco, e neste momento a Activity está visível e em primeiro plano e começa ativa, que é a diferença de onStart;
  • onPause(): Indica que a Activity está parando. Neste momento, você pode fazer alguns trabalhos como armazenar dados e parar a animação, mas não deve ser muito demorado, pois afetará a exibição da nova Activity. OnPause deve ser executado primeiro e o onResume da nova Activity não será implementado;
  • onStop(): Indica que a Activity está prestes a parar, e você pode fazer algum trabalho de reciclagem pesado, como cancelar o broadcast receiver, fechar a conexão de rede, etc., e não deve ser muito demorado;
  • onDestroy(): Indica que a Activity está prestes a ser destruída.Este é o último callback no ciclo de vida da Activity, muitas vezes fazendo trabalho de reciclagem e liberação de recursos;

26. Quais métodos serão chamados quando a Atividade A iniciar outra Atividade B? E se B for um tema transparente ou uma DialogActivity?

Activity A inicia outra Activity B, e o callback é o seguinte:
onPause() da Activity A → onCreate() da Activity B → onStart() → onResume() → onStop() da Activity A;
se B for um tema transparente ou a DialogActivity, então o onStop de A não será chamado de volta;

27. Fale-me sobre a função do método onSaveInstanceState() Quando ele será chamado?

Condições de ocorrência: sob circunstâncias anormais (Atividade é eliminada e recriada quando a configuração do sistema é alterada, Atividade de baixa prioridade é eliminada devido a memória de recurso insuficiente)

  • O sistema chamará onSaveInstanceState para salvar o estado da Activity atual.Este método é chamado antes de onStop e não possui relação de temporização estabelecida com onPause;
  • Quando a atividade for reconstruída, o sistema chamará onRestoreInstanceState e passará o objeto Bundle salvo pelo método onSave (abreviação) para onRestore (abreviação) e onCreate() ao mesmo tempo, para que esses dois métodos possam ser usados ​​para determinar se a atividade A atividade foi reconstruída,
    chame após onStart;

Vinte e oito, fale sobre os quatro modos de inicialização e cenários de aplicação do Activity?

Modo padrão padrão: toda vez que uma atividade é iniciada, uma nova instância será recriada, independentemente de a instância já existir
, a atividade neste modo entrará na pilha de tarefas da atividade que a iniciou por padrão;
modo singleTop stack top multiplexing : se a nova atividade já estiver no topo da pilha de tarefas, a atividade não será recriada e o método onNewIntent será chamado de volta. Se a nova instância da atividade já existir, mas não estiver no topo da pilha, o A atividade ainda será recriada;

Modo de multiplexação em pilha SingleTask: Enquanto a atividade existir em uma pilha de tarefas, a instância não será
recriada e o método onNewIntent será chamado de volta. Nesse modo, quando a atividade A é iniciada , o sistema primeiro procurará se há uma atividade que A deseja Se a
pilha de tarefas não existir, uma pilha de tarefas será recriada e, em seguida, a instância criada de A será colocada na pilha;
modo de instância única singleInstance: Este é um modo singleTask aprimorado, e a atividade com este modo só pode ser localizada separadamente
em uma pilha de tarefas e há apenas uma instância nessa pilha de tarefas;

29. Sabe quais bandeiras são comumente utilizadas nas atividades?

  • FLAG_ACTIVITY_NEW_TASK : corresponde ao modo de inicialização singleTask, e seu efeito é o mesmo que especificar o modo de inicialização em XML;
  • FLAG_ACTIVITY_SINGLE_TOP : corresponde ao modo de inicialização singleTop, e seu efeito é o mesmo que especificar o modo de inicialização em XML;
  • FLAG_ACTIVITY_CLEAR_TOP : quando uma atividade com este sinalizador é iniciada, todas as atividades acima dela na mesma pilha de tarefas serão exibidas. Este flag geralmente aparece junto com o modo singleTask, neste caso,
    se a instância da Activity iniciada já existir, o sistema chamará de volta onNewIntent. Se a atividade iniciada for
    iniciada no modo padrão, ela e as atividades acima dela serão removidas da pilha e o sistema criará uma nova instância de atividade e a colocará na pilha;
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS: As atividades com este sinalizador não aparecerão na lista de atividades do histórico
    ;

30. Como iniciar a Atividade de outros aplicativos?

No caso de acesso garantido, use o Intent implícito para corresponder ao IntentFilter da Activity de destino. O princípio é:
um intent só pode ser iniciado se corresponder à ação, categoria e dados no filtro de intenção de uma Activity no ao mesmo tempo. Atividade;
uma Atividade pode ter vários filtros de intenção, desde que uma intenção corresponda com sucesso a qualquer conjunto de filtros de intenção, a Atividade pode ser iniciada;

31. Fale sobre o ciclo de vida do Fragment?

Os métodos envolvidos em todo o ciclo de vida do Fragment, desde a criação até a destruição, são: onAttach()→onCreate()→onCreateView()→onActivityCreated()→onStart()→onResume()→onPause()→onStop()→onDestroyView( )→onDestroy()→onDetach(), existem muitos métodos com o mesmo nome e função semelhante a Activity, mas os métodos diferentes
são:

  • onAttach(): Chamado quando Fragment e Activity estão associados;
  • onCreateView(): chamado quando o fragmento cria uma view, após onCreate;
  • onActivityCreated(): Chamado quando a atividade associada ao fragmento é concluída onCreate();
  • onDestroyView(): Chamado quando o layout no Fragmento é removido;
  • onDetach(): Chamado quando Fragment e Activity são desassociados;

Trinta e dois, fale sobre a diferença entre Atividade e Fragmento?

Semelhanças: Ambos podem conter layouts e ter seu próprio ciclo de vida

diferença:

  • Comparado com Activity, Fragment tem mais 4 ciclos de callback, o que é mais flexível na operação de controle;
  • O fragmento pode ser escrito diretamente no arquivo XML ou adicionado dinamicamente na Activity;
  • Fragment pode usar show()/hide() ou replace() para alternar Fragment a qualquer momento, e não haverá efeito óbvio ao alternar, e a experiência do usuário será melhor; embora Activity também possa ser alternado, haverá alguns problemas ao alternar entre atividades. Virada de página óbvia ou outros efeitos não dão aos usuários uma boa sensação ao alternar uma pequena parte do conteúdo;

Trinta e três, a diferença entre adicionar e substituir no fragmento (sobreposições de fragmentos)

  • add não reinicializará o fragmento, substituirá sempre. Portanto, se você obtiver os dados no ciclo de vida do fragmento, você os obterá repetidamente se usar substituir;
  • Ao adicionar o mesmo fragmento, não haverá alteração em replace e add reportará um IllegalStateException;
  • Substituir primeiro remove todos os fragmentos com o mesmo id e, em seguida, adiciona o fragmento atual, enquanto adicionar substitui o fragmento anterior. Portanto, se você usar add, geralmente será acompanhado por hide() e show() para evitar sobreposição de layout;
  • Usando add, se o app for colocado em segundo plano ou destruído pelo sistema de outras formas, quando ele for aberto novamente, o fragmento referenciado em hide() será
    destruído bugs de sobreposição de layout, você pode usar replace ou adicione um ao usar o parâmetro add tag;

Trinta e quatro, a diferença entre getFragmentManager, getSupportFragmentManager, getChildFragmentManager?

  • O que getFragmentManager() obtém é o gerenciador do contêiner pai do fragmento onde ele está localizado, e o que getChildFragmentManager() obtém é o gerenciador do subcontêiner no fragmento. Se o fragmento for um fragmento aninhado, você precisará use getChildFragmentManager();
  • Como o Fragment é um componente que aparece apenas na versão 3.0 da API do sistema Android, o sistema acima da 3.0 pode chamar diretamente getFragmentManager() para obter o objeto FragmentManager(), enquanto o sistema abaixo da 3.0 precisa chamar getSupportFragmentManager() para obter indiretamente;

Trinta e cinco, a diferença entre FragmentPagerAdapter e FragmentStatePagerAdapter e cenários de uso

O mesmo ponto: ambos herdam PagerAdapter

A diferença: cada fragmento do FragmentPagerAdapter será armazenado persistentemente no FragmentManager e não será destruído enquanto o usuário puder retornar à página. Portanto, é adequado para páginas com dados relativamente estáticos e um pequeno número de Fragments; FragmentStatePagerAdapter retém apenas a página atual e, quando a página estiver invisível, o Fragment será eliminado e seus recursos serão liberados. Portanto, é adequado para situações em que os dados são mais dinâmicos, ocupam mais memória e possuem muitos Fragments;

pós-escrito

Eu gastei muita energia para resolver esta pergunta da entrevista. Parece um pouco desajeitado copiar as perguntas da entrevista depois de revisá-las. E para não parecer tão desajeitado, pensei especificamente nas perguntas que costumo ver e consultei materiais relevantes para as perguntas mencionadas pelo autor, e coloquei esses materiais nas perguntas da entrevista correspondente. A intenção original de organizar este artigo é lidar com o entrevistador, mas quanto mais eu olho para ele, mais sinto que falta mais, seja a experiência da entrevista compartilhada pelo autor ou os detalhes técnicos compartilhados pelo autor são tão preciosos para mim! Esse processo é como quando íamos para a escola. No início era para atender às exigências de professores e pais, mas conforme fui crescendo, percebi que os ganhos nesse processo eram muito maiores do que as exigências de professores e pais. .

Por fim, o motivo do espaço está aqui. Procuro suprir as deficiências apontadas nas perguntas da entrevista. Espero também que todos que lerem aqui possam encontrar um emprego satisfatório ou encontrar o que desejam no artigo. ! Se você ainda precisa saber mais sobre a análise das respostas às perguntas da entrevista do Android, pode obter o cartão no final do artigo

Não é fácil organizar, suas curtidas, assistir, repostar e marcar estrelas são meu maior incentivo! Desejo que todos possam obter uma oferta satisfatória!

insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/Androiddddd/article/details/131963594
Recomendado
Clasificación