Насколько важный действительно ли расположением является Шрифт, действительно?

Добавление общего кода для разных типов разрешений. Скопируйте пасту с небольшими изменениями. Прочитайте комментарии «TODO» в приведенном ниже коде.

Сделайте следующее действие вашей Launcher Activity:

public class PermissionReqActivity extends AppCompatActivity {

    private static final int CODE_WRITE_SETTINGS_PERMISSION = 332;
    private static String[] PERMISSIONS_ALL = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; //TODO You can Add multiple permissions here.
    private static final int PERMISSION_REQUEST_CODE = 223;
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_permission_req);
        context = this;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            boolean allPermissionsGranted = true;
            ArrayList<String> toReqPermissions = new ArrayList<>();

            for (String permission : PERMISSIONS_ALL) {
                if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                    toReqPermissions.add(permission);

                    allPermissionsGranted = false;
                }
            }
            if (allPermissionsGranted)
                //TODO Now some permissions are very special and require Settings Activity to launch, as u might have seen in some apps. handleWriteSettingsPermission() is an example for WRITE_SETTINGS permission. If u don't need very special permission(s), replace handleWriteSettingsPermission() with initActivity().
                handleWriteSettingsPermission();
            else
                ActivityCompat.requestPermissions(this,
                        toReqPermissions.toArray(new String[toReqPermissions.size()]), PERMISSION_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE) {
            boolean allPermGranted = true;
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Permissions not granted: " + permissions[i], Toast.LENGTH_LONG).show();
                    allPermGranted = false;
                    finish();
                    break;
                }
            }
            if (allPermGranted)
                handleWriteSettingsPermission();//TODO As mentioned above, use initActivity() here if u dont need very special permission WRITE_SETTINGS
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    private void handleWriteSettingsPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.System.canWrite(context)) {
                initActivity();
            } else {
                Toast.makeText(this, "Please Enable this permission for " +
                        getApplicationInfo().loadLabel(getPackageManager()).toString(), Toast.LENGTH_LONG).show();
                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                intent.setData(Uri.parse("package:" + context.getPackageName()));
                startActivityForResult(intent, CODE_WRITE_SETTINGS_PERMISSION);
            }
        }
    }

//TODO You don't need the following onActivityResult() function if u dont need very special permissions.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == CODE_WRITE_SETTINGS_PERMISSION) {
            if (Settings.System.canWrite(this))
                initActivity();
            else {
                Toast.makeText(this, "Permissions not granted: " + Manifest.permission.WRITE_SETTINGS, Toast.LENGTH_LONG).show();
                finish();
            }
        }
    }

    private void initActivity() {
        startActivity(new Intent(this, MainActivity.class));
    }
}
17
задан Daniel Lew 22 April 2009 в 15:31
поделиться

5 ответов

Простой ответ: если это просто мало, то нет. Если это много, тогда да. Если ваше приложение уже использует сборщик мусора, тогда да. Я использовал бы perfmon, чтобы увидеть количество объектов, сидящих вокруг, и число, которое будет повышено до старших поколений, и затем принять решение.

5
ответ дан 30 November 2019 в 14:06
поделиться

Проблема в том, что сборка мусора происходит только при нехватке памяти. Часто неуправляемые дескрипторы более ограничены, чем память, поэтому у вас могут не хватить дескрипторы до того, как GC произойдет, что приведет к ошибкам.

Но для одного или двух экземпляров Font это не повредит вам слишком сильно.

Еще большая проблема заключается в том, что некоторые объекты являются общими и не должны (или не могут) удаляться преждевременно ...

5
ответ дан 30 November 2019 в 14:06
поделиться

Почему бы вам не избавиться от него, как только вы закончите? То, что у нас есть дворники, не означает, что мы должны просто мусорить на улицах. Однако в приведенном примере, если шрифт необходим для жизненного цикла объекта, тогда избавьтесь от шрифта в распоряжении этого объекта. Есть много вещей, которые также упростили бы мой код, но это не оправдывает эти изменения - иногда есть вещи, которые вы должны сделать, даже если это боль.

Всегда полезно привести себя в порядок. Когда вам что-то больше не нужно, избавьтесь от этого. Таким образом, вы можете избежать неприятных условий гонки, исключений нехватки памяти, сбоя при рисовании и длительных сборок мусора, интенсивно использующих процессор.

Я считаю, что это ' Рекомендуется утилизировать одноразовые предметы, если они вам больше не нужны, если для этого нет веской причины (например, если вы не являетесь владельцем объекта). Сложнее отследить основную причину проблемы, чем защищать ее заранее.

Что касается шрифта, MSDN говорит :

Всегда вызывайте Dispose, прежде чем выпускать последний ссылка на шрифт. В противном случае используемые им ресурсы не будут освобождены до тех пор, пока сборщик мусора не вызовет метод Finalize объекта Font.

В нем не говорится, что это за ресурсы, но тот факт, что они явно заявляют, что это должно быть сделано, неявным образом добавляет важность зови Уничтожь.

Сложнее отследить основную причину проблемы, чем защищать ее заранее.

Что касается шрифта, MSDN говорит :

Всегда вызывайте Dispose, прежде чем выпускать последний ссылка на шрифт. В противном случае используемые им ресурсы не будут освобождены до тех пор, пока сборщик мусора не вызовет метод Finalize объекта Font.

В нем не говорится, что это за ресурсы, но тот факт, что они явно заявляют, что это должно быть сделано, неявным образом добавляет важность зови Уничтожь.

Сложнее отследить основную причину проблемы, чем защищать ее заранее.

Что касается шрифта, MSDN говорит :

Всегда вызывайте Dispose, прежде чем выпускать последний ссылка на шрифт. В противном случае используемые им ресурсы не будут освобождены до тех пор, пока сборщик мусора не вызовет метод Finalize объекта Font.

В нем не говорится, что это за ресурсы, но тот факт, что они явно заявляют, что это должно быть сделано, неявным образом добавляет важность зови Уничтожь.

5
ответ дан 30 November 2019 в 14:06
поделиться

Насколько важно избавиться от чего-нибудь , на самом деле? ИМХО, когда вы начинаете задавать подобные вопросы, кажется, что у вас есть проблемы с дизайном в вашем коде. Вы всегда должны избавляться от вещей, которые вам больше не нужны - это называется ответственное программирование.

Возможные решения вашей проблемы:

  • Не проходите вокруг таких объектов, как Fonts. Реализовать логику использования шрифтов в одном месте (один класс), добавить шрифт в качестве поля этого класса и реализовать IDisposable для этого класса.

  • Реализовать класс кэширования шрифтов - вместо создания новых объектов Font с использованием оператора new по всему коду, используйте этот класс, чтобы получить желаемый Font. Класс может иметь логику для повторного использования существующих шрифтов, если это возможно. Или сохранить последние 10 шрифтов в памяти и избавиться от остальных. Реализуйте IDisposable для кеша, который будет вызываться один раз в жизненном цикле вашего приложения.

3
ответ дан 30 November 2019 в 14:06
поделиться

Финализаторы встроены в классы именно потому, что необходима очистка. Независимо от того, есть ли у вас большое или небольшое количество объектов для очистки, рекомендуется очищать их.

GC был создан, чтобы иметь собственный псевдо-разум. Правильно утилизируя ваши объекты, вы позволяете ГХ делать то, что было сделано.

Однако, если вы создаете большое количество объектов шрифтов и утилизируете все из них, может быть полезно вызывать GC соответствующего поколения (вероятно, 0), чтобы инициировать очистку GC самостоятельно в зависимости от на какие виды других объектов вы создаете множество экземпляров. Ваша цель должна состоять в том, чтобы объекты, которые, как вы знаете, не использовались в течение долгого времени, были продвинуты в старшие поколения. Это делает работу GC скромной и подлой.

Просто используйте свое лучшее суждение, и все будет в порядке. Но действительно утилизируйте любой объект с финализатором как обычную практику.

1
ответ дан 30 November 2019 в 14:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: