0

我想在我的应用程序中实现启动画面。我已经这样做了。但目前它只等待 3 秒,然后调用 MainActivity 类。问题在于我有数据要加载,并且在当前设置下,用户必须等待两次。我想要一个加载所有数据的启动画面。我有一个 MainActivity 类,一切都会发生,我有我的 SplashScreen 类。

我想在后台运行的方法在我的 MainClass 中。所以基本上我有我的闪屏类

public class SplashScreenActivity extends AsyncTask<Void, Void, Void> {

@Override
protected Void doInBackground(Void... params) {
    // TODO Auto-generated method stub
    return null;
}

protected void onPostExecute(Void... params) {
    // TODO Auto-generated method stub

}

protected void onCancelled() {
    // TODO Auto-generated method stub
}

}

我也实现了但没有复制导入和包,所以这应该不是问题。现在,如果我理解正确,我需要将应该完成的任务写入 doInBackground 方法。所以我基本上必须从我的其他活动类中调用该方法,对吧?

public MainActivity mA = new MainActivity();

然后在我会写的方法中mA.parseXMLfromURL();

然后我会像这样将主类的意图启动到 onPostExecute 方法中?

protected void onPostExecute(Void... params) {
    Intent mainClass = new Intent(SplashScreenActivity.this, MainActivity.class);
    startActivity(mainClass);

}

如果需要更多信息,我很乐意进一步详细说明。

更新

好吧,在你的评论之后,我尝试了一些不同的方法。

这是我的 oncreate 方法

    public void onCreate(Bundle savedInstanceState) {
    StrictMode.setThreadPolicy(policy);
    super.onCreate(savedInstanceState);
    sv      = new ScrollView(this);
    layout = new LinearLayout(this);
    layout.setOrientation(LinearLayout.VERTICAL);
    sv.addView(layout);
    setContentView(sv);     

    new SplashScreenActivity().execute("URL TO FILE");
}

这是 SplashScreenActivity

public class SplashScreenActivity extends AsyncTask<String, Void, Void> {
public MainActivity mA = new MainActivity();

protected void onPostExecute(Void... params) {
}

protected void onCancelled() {
    // TODO Auto-generated method stub
}

@Override
protected Void doInBackground(String... params) {
    mA.parseXMLfromURL(params);
    return null;
}

}

但这只是返回一个空白屏幕。但是,如果我在主要活动中调用 parseXMLfromURL,它就可以正常工作。

@Raghunandan 在评论中说我错误地创建了该类的实例。如果你能详细说明你的答案,我会很高兴。

更新二

当前的 SplashScreen-Code 如下:

包 de.activevalue.T1000flies;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;

public class SplashScreenActivity extends Activity{

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

    new mTask().execute();
}

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

    MainActivity mA = new MainActivity();
    @Override
    protected Void doInBackground(Void... arg0) {
        mA.parseXML();
        return null;
    }

    protected void onPostExecute(Void... params){
        Intent i = new Intent(SplashScreenActivity.this, MainActivity.class);
        startActivity(i);
        finish();
    }


}

}

使用该代码,应用程序只会停留在启动画面上。我的 XML 解析似乎有问题。这是 XML 解析代码。请注意,当我只是在没有启动画面的情况下启动主要活动时,它可以正常工作

更新三号

我刚开始通过每行设置断点来进行调试。它跳出这条线

rankingDate [k]             = new TextView(this);

其余代码

for(int k = 0; k < metaList.getLength(); k++){

            Node metaNode = metaList.item(k);
            System.out.println(metaList.getLength());
            rankingDate [k]             = new TextView(this);
            rdate       [k]             = new TextView(this);
            numberOE    [k]             = new TextView(this);

            Element metaElement = (Element) metaNode;
            NodeList rankingDateList    = metaElement.getElementsByTagName("date");
            Element rankingDateElement  = (Element) rankingDateList.item(0);
            rankingDateList             = rankingDateElement.getChildNodes();
            rankingDate [k].setText("RankingDate: " + ((Node) rankingDateList.item(0)).getNodeValue());
            layout.addView(rankingDate[k]);

            xmlSerializer.startTag(null, "date");
            xmlSerializer.text(((Node) rankingDateList.item(0)).getNodeValue());
            xmlSerializer.endTag(null, "date");

        }

system.out.println 给了我 1。而 k 是 0。那么为什么它是空指针异常?

4

5 回答 5

3

您应该为 SplashScreen 创建新 Activity --> SplashScreenActivity 扩展 Activity,在清单中声明,然后设置布局;

public SplashScreenActivity extends Activity{

 protected void onCreate(Bundle ...){
  super.onCreate(...);
  setContentView(...);
  new mTask().execute();
 }

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

@Override
protected Void doInBackground(Void... params) {
    // TODO Auto-generated method stub
    return null;
}

protected void onPostExecute(Void... params) {
   Intent mainClass = new Intent(SplashScreenActivity.this, MainActivity.class);
    startActivity(mainClass);
    finish();
}

 }

}
于 2013-10-07T13:35:33.860 回答
1

捎带 nrisezgin 的回答解释了 AsyncTasks 如何在 android 中工作,你几乎就在那里,但需要解决一些其他问题。

第一:在 Android 世界中,您永远不会通过调用其构造函数来初始化活动。活动由操作系统处理,您使用Intents 运行它们。

顺便说一句,您非常接近解决您的问题。您需要获取函数中的任何代码并将其放入您的parseXML函数中并调用它,或者直接将其放入您的方法中。MainActivitySplashScreenActivitydoInBackground

您的doInBackground方法不应调用任何外部活动。

于 2013-10-07T15:32:13.667 回答
0

为什么不只创建 MainActivity。Splash 只是 main.xml 的一个框架布局,在一定时间后会被 setVisibility(View.GONE)。

使用此方法,您只有 1 个活动。因此,更容易处理来自网络的加载数据而不会中断。

于 2013-10-07T15:18:43.337 回答
0

我在一个项目中尝试了完全相同的方法,但我的方法不同。也许它也可以解决您的问题...

首先,mySplashScreenMainActivity

 //main-activtiy xml
 <RelativeLayout ...
     <RelativeLayout id="overlay" visible="true"... //filled parent and had a centered image
     <RelativeLayout id="mainActivity" visible="false"... //the application
  • 应用程序启动
  • 开始你的AsyncTaskService在你的onCreateMethod
  • 如果加载了数据,请发送Notification给您MainActivity并“交换您的视图”,例如

    public void functionCalledOnDataLoaded(){
       //do you init stuff
    
      ((RelativeLayout) findViewById(R.id.overlay)).setVisibility(View.INVISIBLE);
      ((RelativeLayout) findViewById(R.id.mainActivity)).setVisibility(View.VISIBLE);
    

    }

于 2013-10-07T14:34:55.350 回答
0

制作启动画面的一种更简单的方法是让它出现在需要使用Dialogs加载数据的主要活动的前面。解决此问题的最简单方法是覆盖 AsyncTask 中的 onPreExecute() 方法。下面是一个简单的闪屏示例。

MainActivity.java

public class MainActivity extends Activity
{
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new SplashScreen(this).execute();
    }
}

闪屏.java

public class SplashScreen extends AsyncTask<Void, Void, Void>
{
    Context ctxt;
    Dialog splash;

    public SplashScreen(Context ctxt)
    {
        this.ctxt = ctxt;
    }

    protected void onPreExecute()
    {
        splash = new Dialog(ctxt, R.style.full_screen);
        splash.show();
    }

    protected Void doInBackground(Void... ignore)
    {
        //Fetch stuff
        return null;
    }

    protected void onPostExecute(Void ignore)
    {
        splash.dismiss();
    }
}

在您的 res/values/styles.xml 文件中,您希望将以下 xml 用于全屏显示。

<!-- Stuff that's already in here -->

<style name="full_screen" parent="android:Theme.Light">
    <item name="android:windowActionBar">false</item>
    <item name="android:windowNoTitle">true</item>
</style>

<!-- Stuff that's already in here -->

这将为您提供一个非常基本的启动屏幕(即,一个什么都不显示的空白屏幕)。如果您查看 Dialogs API,您可以找到其他自定义方法,允许您使用图片而不是文本以及完全自定义 Dialog 的布局。如果您想要进一步自定义,也请查看DialogFragments 。以这种方式制作初始屏幕的好处是您可以检索所有信息并将其设置在 onPostExecute() 到 MainActivity 中,而不必担心传输数据。

希望这可以帮助!祝你好运。

于 2013-10-07T14:22:21.470 回答