android:立即启动一个活动,然后加载内容

Joh*_*nha 18 java android android-activity

我已经查看了其他问题,博客和文档,似乎无法找到满足我需求的正确答案.我有两个活动,A和B.当我启动活动B(来自A)时,我希望它立即打开,然后在显示进度条时加载所有内容,而不是仅在加载内容时打开活动,使其成为可能好像它冻结了两秒钟.例如Youtube应用程序或Play商店.

这就是我得到的:

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

这是我正在加载的活动:

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) {

    }

}
Run Code Online (Sandbox Code Playgroud)

我不是专家,所以欢迎详细的解释.

注意:我在活动中加载的是这个calandar:https://github.com/prolificinteractive/material-calendarview

问题:如何setContentView()在后台加载?

更新:我遵循了Hitesh Sahu的建议,现在我只有一个活动,其中一个容器被替换为每个片段,我假设在后台加载xml内容的方式对于片段和活动是相同的,但是如果有任何不同,请提及.

Max*_*Max 5

您需要AsyncTask用于加载数据和RelativeLayoutActivityB.

首先初始化变量

private RelativeLayout mRelativeLayout;
Run Code Online (Sandbox Code Playgroud)

onCreate你的活动中AsyncTask像这样执行

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

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

    new PrepareData().execute();
}
Run Code Online (Sandbox Code Playgroud)

把这个AsyncTask类放在ActivityB

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)
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

并设置这个的可见性RelativeLayoutonPreExecuteonPostExecute分别像我已经示例中所示。

更新:

你需要更新你UiUiThread这样的

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

 //put the code here that is giving exception

    }
});
Run Code Online (Sandbox Code Playgroud)


Wac*_*oon 5

您的活动 B 应该有用于加载数据然后显示它的 AsyncTask。您也可以在视图中加载一些默认数据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);
    }

}
Run Code Online (Sandbox Code Playgroud)


Hit*_*ahu 5

可能的解决方案

  • 根据“我不是专家”的猜测,您可能会在每次屏幕切换时创建新活动,并且可能不会清除较旧的活动或重用现有活动。同样,这是我的猜测,我没有看到您的代码,但是我看到开发人员犯了这种错误。很快,您的App的性能会随着时间的流逝而下降,并且最终您的App将会消耗内存。

    如何解决此问题:- 用片段交换片段替换活动比交换活动相对要快,而且您可以重用它们(更多有关此内容)。

  • 您可能在Main Ui线程上做了一些繁重的任务,以寻找编舞者日志,例如-skipped n number of frames app may be doing too much work on main thread

    如何解决此问题: -已在其他答案中进行了解释。

  • 是的,你猜对了,这可能是没有人提到的基本优化事情之一,因为它太明显了,所以感谢你这样做。 (2认同)

小智 1

只需输入这段代码:

Intent goB = new intent(ActivityA.this, ActivityB.class);
startActivity(goB);
Run Code Online (Sandbox Code Playgroud)

在A的onCreate. 然后创建一个 ProgressDialog,如下所示:http ://www.tutorialspoint.com/android/android_progressbar.htm

这将显示 B 加载的进度。你会打电话

progress.setProgress(int)
Run Code Online (Sandbox Code Playgroud)

在B的onCreate中,做某事之后。

例如:

public class B extends Activity {
    public void onCreate(Bundle bundle) {
        progress=new ProgressDialog(this);
        progress.setMessage("Downloading Music");
        progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progress.setIndeterminate(true);
        progress.setProgress(0);
        progress.show();

        //do something
        progress.setProgress(1);
        //do something
        progress.setProgress(2);
        //do something different
        progress.setProgress(3);
    }
    .....
Run Code Online (Sandbox Code Playgroud)

编辑

以下是使用 ProgressBar 的方法:

  • 添加 AProgressBar到 B 布局
  • ProgressBar在 B 中获取对此的引用onCreate(使用findViewById()
  • ProgressBar每次需要时更新您的setProgress(int)(如问题的第一部分所示ProgressDialog
  • 隐藏你ProgressBar使用你的ProgressBar.setVisibility(View.GONE)