2013-10-07 6 views
0

Я хочу реализовать заставки в моем приложении. Я уже это сделал. Но на данный момент он просто ждет 3 секунды, а затем вызывает класс MainActivity. Проблема в том, что у меня есть данные для загрузки, и с текущей настройкой пользователь должен ждать два раза. Я хочу, чтобы экран заставки загружал все данные. У меня есть класс MainActivity, где все происходит, и у меня есть класс SplashScreen.Заставка экрана с AsyncTask

Метод, который я хочу запустить в фоновом режиме, находится в моем 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 сказал в комментариях, что я ошибочно создал экземпляр класса. Был бы рад, если бы вы могли разработать свой ответ.

UPDATE НОМЕР ДВА

Текущий SplashScreen-код имеет следующий вид:

пакет 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-Parsing-код. Обратите внимание, что она работает без каких-либо проблем, когда я только начала основной деятельности wihtout заставки

UPDATE НОМЕР ТРИ

Я только начал отлаживать, сделав линию точек останова в каждой строку.Он выскакивает на этой линии

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. И к 0. Итак, почему это Исключение нулевого указателя?

+2

создание экземпляра класса активности «MainActivity mA = new MainActivity()»? Если это не так, то – Raghunandan

+0

У вас есть данные для загрузки в MainActivity. Там также есть еще одна AsyncTask. Поэтому пользователь ждет дважды. это не ваша проблема? – Nizam

+0

Привет, я обновил его. См. Жирный ** обновление ** для информации. Надеюсь, поможет! – Musterknabe

ответ

2

Вы должны создать новую активность для SplashScreen -> SplashScreenActivity extends 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(); 
} 

} 

} 
+0

Привет, спасибо за ответ. Как раз то, что вы сказали, но теперь оно застряло на экране Splash. Я не получаю сообщений в кошке или консоли журнала. Но хорошо, это не меняет намерения. У меня не было ошибок в коде. Скопировал ваш код и просто добавил вызов метода в 'doInBackground'-method – Musterknabe

+0

@Musterknabe Вы также сделали часть onPostExecute? Код, который вы отправили в редактировании на свой вопрос, не включает это. Отправьте свой точный код. –

+0

@ KasraRahjerdi - Я обновил начальную запись. Пожалуйста, взгляните на конец. – Musterknabe

0

Простой способ сделать экран заставки, чтобы он появится перед вашей основной деятельности, которую необходимо загрузить данные с помощью Dialogs. Самый простой способ сделать это - переопределить метод onPreExecute() в AsyncTask. Ниже приведен простой пример заставки.

MainActivity.java

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

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

SplashScreen.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(); 
    } 
} 

В вашем Рез/значений/файла 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 --> 

Это даст вам очень простой экран (т. Е. Пустой экран, который ничего не говорит). Если вы посмотрите на API диалоговых окон, вы можете найти другие способы его настройки, которые позволяют использовать изображения вместо текста, а также полностью настраивать макет диалогового окна. Также обратите внимание на DialogFragments, если вы хотите еще одну настройку. Преимущество вашего экрана заставки таким образом заключается в том, что вы можете получить всю свою информацию и настроить ее в onPostExecute() на свою MainActivity, не беспокоясь о передаче данных.

Надеюсь, это поможет! Удачи.

+0

Это лучший подход, потому что он отклоняет диалог только после загрузки ресурсов, и при загрузке ресурсов нет необходимости в искусственном счетчике прогресса, хотя я запускаю AsyncTask непосредственно из основного действия и загружаю ресурсы оттуда. Я не верю, что для этого нужно создать новый SplashScreen.java. то есть 'new SplashScreen(). execute();' вызывается из 'onCreate()' в 'MainActivity'. –

0

Я пробовал точно так же в проекте, но мой подход был другим. Может it`could решить вашу проблему, а также ...

первых, мой SplashScreen был оверлей в MainActivity

//main-activtiy xml 
<RelativeLayout ... 
    <RelativeLayout id="overlay" visible="true"... //filled parent and had a centered image 
    <RelativeLayout id="mainActivity" visible="false"... //the application 
  • Применение запущен
  • Начните AsyncTask или Service в вашем 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); 
    

    }

0

Почему бы вам не только создавать MainActivity. Splash - это всего лишь макет фрейма main.xml, и через некоторое время будет установлено значениеVisibility (View.GONE).

Используя этот метод, у вас есть только 1 активность. Таким образом, легче обрабатывать данные нагрузки из сети без прерывания.

+0

Я довольно новичок в async-задачах, поэтому я просто пошел по учебнику. Если бы вы могли разработать с помощью учебника, было бы очень полезно – loomie

1

Piggy-backing ответ nurisezgin, объясняющий, как AsyncTasks работает в android, вы почти там, но вам нужно убрать некоторые другие вещи.

Первый: в Android-мире вы never инициализируете действия, вызывая их конструктор. Операции обрабатываются операционной системой, и вы запускаете их, используя Intent s.

Это далеко от вас, вы очень близки к решению проблемы. Вам нужно взять любой код в функции parseXML вашего MainActivity и положить его либо в свой SplashScreenActivity и позвонить ему, либо просто поместить его прямо в ваш метод doInBackground.

Ваш метод doInBackground не должен вызывать никаких внешних действий.

+0

Эй, но в parseXML-методе я добавляю вещи в макет класса MainActivity. Как я могу справиться с этим? Я имею в виду, я понимаю вашу мысль, но что мне делать, когда вы хотите изменить макет другого класса? – Musterknabe

+0

Любая вещь, требующая потока пользовательского интерфейса, должна быть выполнена на вашем 'onPostExecute()', если вы даете больше подробностей о том, что вы делаете, я могу вам помочь, но для общего случая загрузки чего-либо из Интернета и отображения это, я бы сказал, не делайте заставки и вместо этого показывайте панель загрузки в вашей другой деятельности или сохраняйте данные где-нибудь. –

+0

Привет, что именно я делаю: Приложение запускается, а затем получает данные из XML через URL-адрес. Затем он переходит к чтению данных и сохраняет их в TextViews и отображает их через forloop и использует массивы. Я хотел реализовать Splash-Screen, чтобы пользователь увидел логотип и не должен ждать, пока приложение задается вопросом, почему это так долго. Но да, также будет работать индикатор выполнения, а не экран заставки. Но все учебные пособия по эталону, которые я нашел там, где также выполнялись асинхронные задачи, будут иметь такую ​​же проблему. Потому что я думаю, что передавать все данные в onPostExecute слишком много. – Musterknabe

Смежные вопросы