java एंड्रॉइड: तुरंत एक गतिविधि शुरू करें और फिर सामग्री को लोड करें




android android-activity (8)

मैंने अन्य प्रश्नों, ब्लॉगों और दस्तावेजों में देखा है और मेरी जरूरतों के लिए सही जवाब नहीं मिल सकता है मेरे पास दो गतिविधियां हैं, ए और बी। जब मैं गतिविधि बी (ए से) शुरू कर देता हूं तो मैं तुरंत इसे खोलना चाहता हूं और फिर सामग्री को लोड होने पर गतिविधि को खोलने के बजाय प्रगति बार दिखाते समय सभी सामग्री लोड करना चाहता हूं लगता है कि यह दो सेकंड के लिए स्थिर है। एक उदाहरण यूथट्यूब ऐप या प्ले स्टोर होगा।

यही मुझे मिला है:

Button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent goB = new intent(ActivityA.this, ActivityB.class);
            startActivity(goB);
        }
    });

यह वह गतिविधि है जो मैं लोड कर रहा हूं:

public class ActivityB extends AppCompatActivity implements OnDateSelectedListener, OnMonthChangedListener {

    private static final DateFormat FORMATTER = SimpleDateFormat.getDateInstance();

    @Bind(R.id.calendarView) MaterialCalendarView widget;
    @Bind(R.id.textView) TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_c_calendar);
        ButterKnife.bind(this);
        widget.setOnDateChangedListener(this);
        widget.setOnMonthChangedListener(this);
        textView.setText(getSelectedDatesString());

    }

    @Override
    public void onDateSelected(@NonNull MaterialCalendarView widget, @Nullable CalendarDay date, boolean selected) {
        textView.setText(getSelectedDatesString());
    }

    private String getSelectedDatesString() {
        CalendarDay date = widget.getSelectedDate();
        if (date == null) {
            return "No Selection";
        }
        return FORMATTER.format(date.getDate());
    }

    @Override
    public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) {

    }

}

मैं एक विशेषज्ञ नहीं हूं, इसलिए विस्तृत स्पष्टीकरण का स्वागत किया जाएगा।

नोट: गतिविधि में जो मैं लोड कर रहा हूं वह यह कैलंडर है: https://github.com/prolificinteractive/material-calendarview

प्रश्न: पृष्ठभूमि पर setContentView() कैसे लोड करें?

अद्यतन: मैंने हितेश साहू की सलाह का पालन किया और अब मेरे पास एक कंटेनर के साथ एक गतिविधि है जो प्रत्येक टुकड़े के लिए बदल दी जाती है, मैं पृष्ठभूमि में XML सामग्री को लोड करने का तरीका मान रहा हूँ, एक टुकड़ा और एक गतिविधि के लिए समान होगा, लेकिन अगर कोई भिन्नता है तो कृपया उल्लेख करें


आप एक AsyncTask का उपयोग कर सकते हैं

उदाहरण: इसे अपने गतिविधि पेज में जोड़ें (कॉन्टेट () के बाहर)

class OnLoading extends AsyncTask<Void,Void,Void>{

ProgressDialog pd;
@Override
protected void onPreExecute() {
    super.onPreExecute();
    pd=new ProgressDialog(Main2Activity.this);
    pd.setTitle("Title");
    pd.setMessage("Message");
    pd.setCancelable(false);
    pd.show();
}

@Override
protected Void doInBackground(Void... params) {
    //
    //Do all your loading stuff here
    //
    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
    pd.dismiss();
}

@Override
protected void onProgressUpdate(Void... values) {
    super.onProgressUpdate(values);
}
}    

इस वर्ग को कॉलिंग द्वारा निष्पादित किया जाता है

new OnLoading().execute();

इस कोड को कार्यान्वित करने पर पहले क्रिया निष्पादित किया जाएगा PreExecute-> doInBackGround-> onPostExecute । प्रगति अद्यतन का उपयोग कॉलिंग करके doInBackGround फ़ंक्शन से कुछ प्रगति दिखाने के लिए किया जा सकता है

publishProgress(value);

यहां सबसे पहले प्रगतिदर्शिका दिखाया जाएगा। DoInBackground में datas आदि को लोड करने के लिए कोड प्रदान करें। जैसा कि नाम का अर्थ है आप इस फ़ंक्शन में लिखते हैं, पृष्ठभूमि में निष्पादित किया जाएगा। इस फ़ंक्शन को निष्पादन पूर्ण होने के बाद, प्रगति संवाद को onPostExecute () में खारिज कर दिया जाएगा।


संभावित समाधान

  • "मैं विशेषज्ञ नहीं हूं " से मेरा अनुमान है कि आप हर स्क्रीन स्विचिंग पर नई गतिविधि का निर्माण कर सकते हैं और संभावित रूप से पुराने को साफ़ नहीं कर रहे हैं या मौजूदा गतिविधि का पुन: उपयोग नहीं कर रहे हैं। फिर यह मेरा अनुमान है मैंने आपके कोड को नहीं देखा है, लेकिन मैंने डेवलपर्स को इस तरह की गलतियों को देखा है। जल्द ही अपने ऐप के प्रदर्शन से समय के साथ नीचा हो जाएगा और आपका ऐप मेमोरी खाएगा।

    इसे कैसे ठीक करें : - गतिविधियों को बदलने के साथ टुकड़े स्विचिंग टुकड़े की तुलना में अधिक तेजी से गतिविधियों को बदलने के लिए प्लस आप उन्हें पुनः उपयोग कर सकते हैं ( इस बारे में अधिक )।

  • कोरियोग्राफर लॉग के लिए मेन यूआई थ्रेड लुक पर कुछ भारी काम हो सकता है - skipped n number of frames app may be doing too much work on main thread

    इसे कैसे ठीक करें: - पहले से अन्य उत्तरों में समझाया गया है।


आपकी गतिविधि बी में डेटा लोड करने और फिर उसे प्रदर्शित करने के लिए AsyncTask होना चाहिए। इसके अलावा आप OnPreExecute() अंदर कुछ डिफ़ॉल्ट डेटा को लोड कर सकते हैं OnPreExecute()

@Override
protected void onCreate(Bundle savedInstanceState) {
    setupViews();
}

private void setupViews(){
    someView1 = (TextView) findViewById(R.id.some_view_id1);
    someView2 = (TextView) findViewById(R.id.some_view_id2);
    someView3 = (ImageView) findViewById(R.id.some_view_id3);
    progressBar = (ProgressBar) findViewById(R.id.progress_bar_id);
    new LoadDataForActivity().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

private class LoadDataForActivity extends AsyncTask<Void, Void, Void> {

String data1;
String data2;
Bitmap data3;

    @Override
    protected void onPreExecute() {
        progressBar.setVisibility(View.VISIBLE);
    }
    @Override
    protected Void doInBackground(Void... params) {
        data1 = loadData1();
        data2 = loadData2();
        data3 = loadData3();
    }

    @Override
    protected void onPostExecute(Void result) {
        someView1.setText(data1);
        someView2.setText(data2);
        someView3.setImageBitmap(data3);
        progressBar.setVisibility(View.GONE);
    }

}

टुकड़ों के लिए अपनी गतिविधियों को बदलें और AsynkTask का उपयोग करें

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_subjects, container, false);

    new addDataAsync().execute();

    return view;
}

    private class addDataAsync extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... param) {

        //Do your background stuff, initializations, downloads etc
        return null;
    }

    protected void onPostExecute(Void param) {

        // Do the stuff that changes the UI, adding views etc

    }

आपको जो कुछ भी तुरंत प्रदर्शित करने की आवश्यकता नहीं है, उसके लिए आपको एक व्यू स्टब का उपयोग करना चाहिए। एक्सएमएल लेआउट्स से विचारों को फुलाते हुए काफी महंगा ऑपरेशन हो सकता है, खासकर अगर आपके पास कई नेस्टेड व्यू ग्रुप हैं एक व्यूस्टबबल ऑन-क्रेटिंग () को आपकी पसंद के स्थान पर अनावश्यक लेआउट मुद्रास्फीति को ऑफसेट करने से काम करता है, जो आपकी गतिविधि को स्क्रीन पर शीघ्र प्रदर्शित होने में अनुवाद करता है।

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView 
        android:id="@+id/textview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ProgressBar 
        android:id="@+id/progressbar"
        android:layout_width="match_parent"
        android:indeterminate="true"
        android:layout_height="match_parent"/>

    <ViewStub 
        android:id="@+id/view_stub"
        android:inflatedId="@+id/calendarView"
        android:layout="@layout/my_expensive_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

अब जब प्रगतिबार स्क्रीन पर प्रदर्शित होता है, तो हम CreateCreate () पर, जैसे PostCreate () या onResume () पर एक जीवनचक्र कॉल में व्यूस्टब को फुला सकते हैं। आप निम्न का उपयोग कर प्राप्त कर सकते हैं:

viewStub.setOnInflateListener(new OnInflateListener() {
    void onInflate(ViewStub stub, View inflated) {

        calendarView = (MaterialCalendarView) inflated.findViewById(R.id.calendarView);
        // perform any calendar setup here
        progressBar.setVisibility(View.GONE); // hide progressbar, no longer needed
    }
});
viewStub.inflate();

यह निश्चित रूप से आपके व्यू पदानुक्रम का निरीक्षण करने के लिए मूल्यवान होगा, और जहां संभव हो वहां नेस्टेड दृश्य समूह को सरल करना होगा, क्योंकि यह प्रदर्शन को देखने के लिए वास्तव में एक हिट का कारण बन सकता है। यदि आपका संपूर्ण ऐप धीमा है, तो यह मेमोरी रिसाव जैसी अधिक से अधिक समस्याओं का संकेत दे सकता है, जिसे आप लीककैनारी से पता लगा सकते हैं।


ActivityB में गोलाई सर्किल प्रदर्शित करने के लिए आपको डेटा और RelativeLayout को लोड करने के लिए AsyncTask का उपयोग AsyncTask

पहले चर को प्रारंभ करें

private RelativeLayout mRelativeLayout;

और अपनी गतिविधि के AsyncTask इस तरह AsyncTask निष्पादित करें

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mRelativeLayout = (RelativeLayout) findViewbyID(R.id.loadingCircle);

    new PrepareData().execute();
}

ActivityB में इस AsyncTask वर्ग को रखें

private class PrepareData extends AsyncTask<Void, Void, Void> {

    protected void onPreExecute(Void param) {
        // THIS WILL DISPLAY THE PROGRESS CIRCLE
        mRelativeLayout.setVisibility(View.VISIBLE)


    }

    protected Void doInBackground(Void... param) {

        // PUT YOUR CODE HERE TO LOAD DATA

        return null;
    }

    protected void onPostExecute(Void param) {
        // THIS WILL DISMISS CIRCLE
        mRelativeLayout.setVisibility(View.GONE)
}

और XML में यह लेआउट शामिल है

संवाद के बिना ProgressBar पाने के लिए इसका उपयोग करना है

<RelativeLayout
    android:id="@+id/loadingCircle"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone"
    android:gravity="center" >

<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:indeterminate="true" />
</RelativeLayout>

और इस RelativeLayout की onPreExecute और onPostExecute पर दृश्यता सेट क्रमशः जैसे मैं उदाहरण में दिखाया है।

अद्यतन करें:

आपको इस तरह UiThread में अपने Ui को अपडेट करने की आवश्यकता है

runOnUiThread(new Runnable() {
 @Override
 public void run() {

 //put the code here that is giving exception

    }
});

सबसे पहले आपकी गतिविधि को इस रूप में प्रारंभ करें

startActivity(new intent(A.this, B.class));

जो कुछ भी आपने चुना है, उसके बाद यहां बताया गया है कि आपकी गतिविधि बी को कैसे काम करना चाहिए।

 class B extends AppCompatActivity implements OnDateSelectedListener, OnMonthChangedListener {

  private static final DateFormat FORMATTER = SimpleDateFormat.getDateInstance();

  @Bind(R.id.calendarView) MaterialCalendarView widget;
  @Bind(R.id.textView) TextView textView;

  ProgressDialog progressDialog;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    if(!B.this.isFinishing() && progressDialog != null && !progressDialog.isShowing()) {
        progressDialog.show();
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
    @Override
    public void run() {
      ButterKnife.bind(B.this);
      widget.setOnDateChangedListener(B.this);
      widget.setOnMonthChangedListener(B.this);
      textView.setText(getSelectedDatesString());

      if(!B.this.isFinishing() && progressDialog != null &&  progressDialog.isShowing()) {
        progressDialog.hide();
      }
    }, 1500);
  }

  @Override
  public void onDateSelected(@NonNull MaterialCalendarView widget, @Nullable CalendarDay date, boolean selected) {
      textView.setText(getSelectedDatesString());
  }

  private String getSelectedDatesString() {
    CalendarDay date = widget.getSelectedDate();
    if (date == null) {
        return "No Selection";
    }
    return FORMATTER.format(date.getDate());
  }

  @Override
  public void onMonthChanged(MaterialCalendarView widget, CalendarDay date) {

  }
}

संपादित करें: @ Andre99 के रूप में प्रगति पट्टी का उपयोग करते हुए दिखाया गया है:

-बेट लेआउट के लिए एक प्रगति-बड़बड़ाना जोड़ें

बी की ऑन-क्रेेट में इस प्रगति बियर का एक संदर्भ प्राप्त करें (ढूंढें वीवीआईआईडी () का उपयोग करें

-प्रत्येक प्रगति (प्रगति) के साथ-साथ अपनी प्रगति-दर-अद्यतन करें (जैसा कि ProgressDialog के लिए प्रश्न के पहले भाग में दिखाया गया है)

अपनी प्रगति बरकरार रखें- अपनी प्रगति बरारा.विशेषता (देखें। जीन)


आप निम्न कोड की कोशिश कर सकते हैं:

Intent intent= new Intent(currentActivity.this, targetActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);

आशा है, यह ठीक से काम करेगा। शुभकामनाएँ।





android-activity