ভাগ করা পছন্দগুলি অ্যাক্সেস করা কি ইউআই থ্রেডের বাইরে করা উচিত?


113

জিঞ্জারব্রেড প্রকাশের সাথে সাথে আমি কয়েকটি নতুন এপিআই'র সাথে পরীক্ষা-নিরীক্ষা করছি, যার মধ্যে একটি হ'ল স্ট্রাইকমোড

আমি লক্ষ্য করেছি যে সতর্কতার একটি হল getSharedPreferences()

এটি হ'ল সতর্কতা:

StrictMode policy violation; ~duration=1949 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=23 violation=2

এবং এটি getSharedPreferences()ইউআই থ্রেডে কল করার জন্য দেওয়া হচ্ছে।

করা উচিত SharedPreferencesএকসেস করুন, এবং সত্যিই UI 'তে থ্রেড বন্ধ করা পরিবর্তন?


আমি সর্বদা ইউআই থ্রেডে আমার পছন্দের কাজগুলি করেছি। যদিও আমি অনুমান করি এটি আইও অপারেশন হওয়ার কারণে এটি বোধগম্য হয়েছে
ফালমারি

উত্তর:


184

আমি খুশি যে আপনি ইতিমধ্যে এটি নিয়ে খেলছেন!

কিছু বিষয় লক্ষণীয়: (অলস বুলেট আকারে)

  • এটি যদি আপনার সমস্যাগুলির মধ্যে সবচেয়ে খারাপ হয় তবে আপনার অ্যাপ্লিকেশনটি সম্ভবত কোনও ভাল জায়গায়। :) লেখাগুলি পড়ার চেয়ে সাধারণত ধীর হয়, তবে নিশ্চিত হয়ে নিন যে আপনি কমিট () এর পরিবর্তে SharedPreferencesd $ Editor.apply () ব্যবহার করছেন। প্রয়োগ () জিবি এবং অ্যাসিঙ্কে নতুন (তবে সর্বদা নিরাপদ, জীবনচক্রের স্থানান্তর সম্পর্কে সতর্ক)। আপনি শর্তসাপেক্ষে জিবি + তে অ্যাপ্লিকেশন কল () এবং ফ্রয়েয়েতে বা নীচে কমিট () করতে কল করতে প্রতিবিম্বটি ব্যবহার করতে পারেন। আমি কীভাবে এটি করব তার নমুনা কোড সহ একটি ব্লগপোস্ট করব।

লোডিং সম্পর্কিত, যদিও ...

  • একবার লোড হয়ে গেলে, ভাগ করা অগ্রাধিকারগুলি হ'ল সিলেক্টন এবং ক্যাশেড প্রক্রিয়া-ভিত্তিক। সুতরাং আপনি এটি যত তাড়াতাড়ি লোড করতে চান যাতে আপনার এটি প্রয়োজন হওয়ার আগে মেমরির মধ্যে রাখতে পারেন। (এটি ছোট হিসাবে ধরে নেওয়া, এটি যেমন হওয়া উচিত যদি আপনি SharedPreferences ব্যবহার করেন তবে একটি সাধারণ এক্সএমএল ফাইল ...) ভবিষ্যতে কোনও ব্যবহারকারী কোনও বোতাম ক্লিক করলে আপনি এটিকে দোষ দিতে চান না।

  • তবে আপনি যখনই প্রসঙ্গকে বলুন .getSharedPreferences (...), ব্যাকিং এক্সএমএল ফাইলটি পরিবর্তিত হয়েছে কিনা তা স্থিতিযুক্ত, তাই আপনি যেভাবেই ইউআই ইভেন্ট চলাকালীন সেই পরিসংখ্যানগুলি এড়াতে চাইবেন। একটি স্ট্যাটাসটি সাধারণত দ্রুত হওয়া উচিত (এবং প্রায়শই ক্যাশে থাকে) তবে ইয়্যাফসের সাথে একযোগে চলার পথে খুব বেশি কিছু থাকে না (এবং প্রচুর অ্যান্ড্রয়েড ডিভাইস ইয়াফগুলিতে চালিত হয় ... ড্রয়েড, নেক্সাস ওয়ান ইত্যাদি) তাই আপনি যদি ডিস্ক এড়ান তবে , আপনি অন্য ফ্লাইট বা মুলতুবিযুক্ত ডিস্ক ক্রিয়াকলাপের পিছনে আটকা পড়া এড়াতে পারেন।

  • সুতরাং আপনি সম্ভবত আপনার অনক্রিটের সময় ভাগ করা পছন্দগুলি লোড করতে চান () এবং স্ট্যাটাকে এড়িয়ে একই উদাহরণটি পুনরায় ব্যবহার করতে চান।

  • তবে যদি ওনক্রিট () এর সময় আপনার নিজের পছন্দগুলির প্রয়োজন না হয় তবে লোডিং সময়টি আপনার অ্যাপ্লিকেশনটির শুরু অপ্রয়োজনীয়ভাবে স্টল করে দিচ্ছে, তাই ফিউচারটাস্ক <SharedPreferences> সাবক্লাসের মতো এমন কিছু থাকা ভাল। যা নতুন সেটকে সেট করে set () ফিউচারটাস্ক সাবক্লাসের মান। তারপরে যখনই আপনার এটি প্রয়োজন হয় তখনই আপনার ফিউচারটাস্ক <শেরেডপ্রিফারেন্সেস> এর সদস্যটিকে সন্ধান করুন এবং এটি। আমি এটিকে হ্যানিকম্বের দৃশ্যের আড়ালে স্বচ্ছভাবে করার পরিকল্পনা করছি। আমি কিছু নমুনা কোড প্রকাশ করার চেষ্টা করব যা এই অঞ্চলে সেরা অনুশীলনগুলি দেখায়।

আগামী সপ্তাহে (গুলি) স্ট্রাইকমোড সম্পর্কিত বিষয়ে আসন্ন পোস্টগুলির জন্য অ্যান্ড্রয়েড বিকাশকারী ব্লগটি দেখুন Check


বাহ, সোজা উত্স থেকে এই জাতীয় একটি পরিষ্কার উত্তর পাওয়ার প্রত্যাশা করছিল না! অনেক ধন্যবাদ!
কটনবলপপস

9
বিস্ময়কর এই পোস্টটির নতুন পাঠকদের সুবিধার্থে, উপরে ব্র্যাড ফিৎসপ্যাট্রিক দ্বারা উল্লিখিত ব্লগ পোস্টের লিঙ্কটির নীচে সন্ধান করুন: ব্র্যাড দ্বারা কঠোর মোডে অ্যান্ড্রয়েড বিকাশকারীদের ব্লগ পোস্ট । পোস্টটি শেয়ারডপ্রেফারেন্সগুলি স্টোর করার জন্য অ্যান্ড্রয়েড সংস্করণের উপর ভিত্তি করে প্রয়োগ করুন (জিঞ্জারব্রেড থেকে) বা কমিট (ফ্রয়েও) ব্যবহার করার জন্য স্যাম্পল কোডের একটি লিঙ্কও রয়েছে: [শর্তসাপেক্ষে প্রয়োগ বা প্রতিশ্রুতিবদ্ধ ব্যবহার করুন) ( Code.google.com/p/zippy-android / উত্স / ব্রাউজ / ট্রাঙ্ক / উদাহরণ /… )
টনি এম

4
এটি কি এখনও আইসিএস \ জেবি সম্পর্কিত?
একাত্জ

5

ভাগ করা পছন্দগুলি অ্যাক্সেস করতে বেশ সময় নিতে পারে কারণ সেগুলি ফ্ল্যাশ স্টোরেজ থেকে পড়ে read আপনি অনেক পড়েন? সম্ভবত আপনি তখন অন্য কোনও ফর্ম্যাট ব্যবহার করতে পারেন, যেমন একটি এসকিউএল ডাটাবেস।

তবে স্ট্রিক্টমোড ব্যবহার করে আপনি যা কিছু খুঁজে পান তা ঠিক করবেন না। বা ডকুমেন্টেশন উদ্ধৃত করতে:

তবে স্ট্রাইকডমোড যা সন্ধান করে তা ঠিক করতে বাধ্য হবেন না। বিশেষত, ডিস্ক অ্যাক্সেসের অনেকগুলি ক্ষেত্রে প্রায়শই স্বাভাবিক ক্রিয়াকলাপটি চলাকালীন প্রয়োজনীয়। দুর্ঘটনাক্রমে আপনি যে কাজগুলি করেছেন তা সন্ধান করতে স্ট্রাইকমোড ব্যবহার করুন। যদিও ইউআই থ্রেডের নেটওয়ার্ক অনুরোধগুলি প্রায় সবসময়ই একটি সমস্যা।


6
তবে এসকিউএলাইট এমন ফাইলও নয় যা অবশ্যই ফ্ল্যাশ স্টোরেজ থেকে পড়তে হবে - তবে একটি পছন্দের ফাইলের তুলনায় আরও বড় এবং জটিল। আমি ধরে নিচ্ছি যে, পছন্দগুলির সাথে সম্পর্কিত পরিমাণের পরিমাণের জন্য, একটি এসকিউএলাইট ডাটাবেস তখন একটি পছন্দ ফাইলটি আরও দ্রুত হবে।
টম

এটাই সঠিক. ব্র্যাড যেমন ইতিমধ্যে উল্লেখ করেছে, এটি প্রায় সবসময়ই কোনও সমস্যা নয় - এবং তিনি একবারে ভাগ করা পছন্দগুলি (সম্ভবত ফিউচারটাস্ক ব্যবহার করে কোনও থ্রেডেও) লোড করা এবং একক দৃষ্টান্তের যেকোন সম্ভাব্য অ্যাক্সেসের জন্য এটি রাখা ভাল ধারণা বলে উল্লেখ করেছেন।
মিরিচেল্ট

5

ব্র্যাডের উত্তর সম্পর্কে একটি সূক্ষ্মতা: এমনকি আপনি যদি ওনক্রিট () তে ভাগ করা পছন্দগুলি লোড করেন তবে আপনার সম্ভবত পটভূমির থ্রেডের মানগুলি পড়া উচিত কারণ গেটস্ট্রিং () ইত্যাদি সমাপ্ত ফাইলের পছন্দ শেষ না হওয়া অবধি ব্লক (পটভূমির থ্রেড):

public String getString(String key, String defValue) {
    synchronized (this) {
        awaitLoadedLocked();
        String v = (String)mMap.get(key);
        return v != null ? v : defValue;
    }
}

সম্পাদনা () এছাড়াও একইভাবে ব্লক করে, যদিও প্রয়োগ () অগ্রভাগের থ্রেডে নিরাপদ বলে মনে হয়।

(বিটিডব্লিউ দুঃখিত এটি এখানে রাখার জন্য। আমি ব্র্যাডের উত্তরের মন্তব্য হিসাবে এটি করতে পারতাম, তবে আমি কেবল যোগ দিয়েছি এবং এটি করার মতো যথেষ্ট খ্যাতি নেই don't)


1

আমি জানি এটি একটি পুরানো প্রশ্ন তবে আমি আমার পদ্ধতির ভাগ করতে চাই। আমি দীর্ঘ পড়ার সময় ছিলাম এবং ভাগ করা পছন্দসমূহ এবং বিশ্ব অ্যাপ্লিকেশন শ্রেণীর সংমিশ্রণ ব্যবহার করেছি:

ApplicationClass:

public class ApplicationClass extends Application {

    private LocalPreference.Filter filter;

    public LocalPreference.Filter getFilter() {
       return filter;
    }

    public void setFilter(LocalPreference.Filter filter) {
       this.filter = filter;
    }
}

LocalPreference:

public class LocalPreference {

    public static void saveLocalPreferences(Activity activity, int maxDistance, int minAge,
                                            int maxAge, boolean showMale, boolean showFemale) {

        Filter filter = new Filter();
        filter.setMaxDistance(maxDistance);
        filter.setMinAge(minAge);
        filter.setMaxAge(maxAge);
        filter.setShowMale(showMale);
        filter.setShowFemale(showFemale);

        BabysitApplication babysitApplication = (BabysitApplication) activity.getApplication();
        babysitApplication.setFilter(filter);

        SecurePreferences securePreferences = new SecurePreferences(activity.getApplicationContext());
        securePreferences.edit().putInt(Preference.FILER_MAX_DISTANCE.toString(), maxDistance).apply();
        securePreferences.edit().putInt(Preference.FILER_MIN_AGE.toString(), minAge).apply();
        securePreferences.edit().putInt(Preference.FILER_MAX_AGE.toString(), maxAge).apply();
        securePreferences.edit().putBoolean(Preference.FILER_SHOW_MALE.toString(), showMale).apply();
        securePreferences.edit().putBoolean(Preference.FILER_SHOW_FEMALE.toString(), showFemale).apply();
    }

    public static Filter getLocalPreferences(Activity activity) {

        BabysitApplication babysitApplication = (BabysitApplication) activity.getApplication();
        Filter applicationFilter = babysitApplication.getFilter();

        if (applicationFilter != null) {
            return applicationFilter;
        } else {
            Filter filter = new Filter();
            SecurePreferences securePreferences = new SecurePreferences(activity.getApplicationContext());
            filter.setMaxDistance(securePreferences.getInt(Preference.FILER_MAX_DISTANCE.toString(), 20));
            filter.setMinAge(securePreferences.getInt(Preference.FILER_MIN_AGE.toString(), 15));
            filter.setMaxAge(securePreferences.getInt(Preference.FILER_MAX_AGE.toString(), 50));
            filter.setShowMale(securePreferences.getBoolean(Preference.FILER_SHOW_MALE.toString(), true));
            filter.setShowFemale(securePreferences.getBoolean(Preference.FILER_SHOW_FEMALE.toString(), true));
            babysitApplication.setFilter(filter);
            return filter;
        }
    }

    public static class Filter {
        private int maxDistance;
        private int minAge;
        private int maxAge;
        private boolean showMale;
        private boolean showFemale;

        public int getMaxDistance() {
            return maxDistance;
        }

        public void setMaxDistance(int maxDistance) {
            this.maxDistance = maxDistance;
        }

        public int getMinAge() {
            return minAge;
        }

        public void setMinAge(int minAge) {
            this.minAge = minAge;
        }

        public int getMaxAge() {
            return maxAge;
        }

        public void setMaxAge(int maxAge) {
            this.maxAge = maxAge;
        }

        public boolean isShowMale() {
            return showMale;
        }

        public void setShowMale(boolean showMale) {
            this.showMale = showMale;
        }

        public boolean isShowFemale() {
            return showFemale;
        }

        public void setShowFemale(boolean showFemale) {
            this.showFemale = showFemale;
        }
    }

}

মেইনএ্যাকটিভিটি (এমন ক্রিয়াকলাপ যা আপনার আবেদনে প্রথমে কল হয়):

LocalPreference.getLocalPreferences(this);

পদক্ষেপগুলি ব্যাখ্যা করা হয়েছে:

  1. প্রধান ক্রিয়াকলাপটি getLocalPreferences (এটি) -> এটি আপনার পছন্দগুলি পড়বে, আপনার অ্যাপ্লিকেশন শ্রেণিতে ফিল্টার অবজেক্টটি সেট করবে এবং এটিকে ফিরিয়ে দেবে calls
  2. আপনি যখন অ্যাপ্লিকেশনটিতে অন্য কোথাও getLocalPreferences () ফাংশনটি কল করবেন তখন অ্যাপ্লিকেশন শ্রেণিতে এটি আরও দ্রুত যা এটি উপলব্ধ নেই তা প্রথমে পরীক্ষা করে দেখুন।

উল্লেখ্য: যদি একটি অ্যাপ্লিকেশন ব্যাপক পরিবর্তনশীল শূন্য থেকে ভিন্ন সবসময় চেক, কারণ -> http://www.developerphil.com/dont-store-data-in-the-application-object/

অ্যাপ্লিকেশন অবজেক্টটি চিরকালের স্মৃতিতে থাকবে না, এটি মারা যাবে। জনপ্রিয় বিশ্বাসের বিপরীতে, অ্যাপটি স্ক্র্যাচ থেকে পুনরায় আরম্ভ হবে না। অ্যান্ড্রয়েড একটি নতুন অ্যাপ্লিকেশন অবজেক্ট তৈরি করবে এবং সেই অ্যাপ্লিকেশনটিকে প্রথম স্থানে হত্যা করা হয়নি এমন ধারণা দেয়ার আগে ব্যবহারকারীরা এমন কার্যকলাপ শুরু করবে।

যদি আমি নালটি পরীক্ষা না করে থাকি তবে ফিল্টার অবজেক্টে getMaxDistance () উদাহরণ হিসাবে কল করার সময় আমি একটি নালপয়েন্টার নিক্ষেপ করার অনুমতি দেব (যদি অ্যাপ্লিকেশন অবজেক্টটি অ্যান্ড্রয়েড দ্বারা মেমরি থেকে সরিয়ে নেওয়া হয়)


0

ভাগ করা পছন্দসই ক্লাসটি ডিস্কের এক্সএমএল ফাইলগুলির মধ্যে কিছু পড়তে এবং লেখার কাজ করে, তাই অন্য কোনও আইও অপারেশনের মতো এটিও অবরুদ্ধ হতে পারে। SharedPreferences- এ বর্তমানে সঞ্চিত ডেটা পরিমাণটি API কলগুলির দ্বারা গ্রহণ করা সময় এবং সংস্থানকে প্রভাবিত করে। ন্যূনতম পরিমাণে তথ্যের জন্য ডেটা পেতে / রাখার জন্য এটি কয়েক মিলিসেকেন্ডের (কখনও কখনও মিলিসেকেন্ডের চেয়েও কম) বিষয়। তবে কোনও বিশেষজ্ঞের দৃষ্টিকোণ থেকে ব্যাকগ্রাউন্ডে এপিআই কল করে কর্মক্ষমতা উন্নত করা গুরুত্বপূর্ণ হতে পারে। একটি অ্যাসিনক্রোনাস শেয়ার্ড প্রেফারেন্সের জন্য আমি এটি পরীক্ষা করার পরামর্শ দিই ডেটুম লাইব্রেরিটি ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.