Android活动正在运行两次
我在nexus 7 2013上运行我的应用程序,在logcat中,我注意到一些日志运行了两次。在写了更多的日志之后,我断定每个活动都在平板电脑上运行两次。奇怪的想法是,在手机上(LG G3或三星Galaxy S4 mini)日志只能打印一次。Android活动正在运行两次
在做了一些研究之后,我尝试添加android:launchMode="singleTop"
或singleTask
或singleInstance
但没有任何工作。此外,我还有一些意图与国旗活动:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
和2 AsyncTasks
。
有没有一种方式,意图或asynctask导致问题?
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.marian.digimusicstream" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--
To retrieve OAuth 2.0 tokens or invalidate tokens to disconnect a user. This disconnect
option is required to comply with the Google+ Sign-In developer policies
-->
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> <!-- To retrieve the account name (email) as part of sign-in: -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppBaseTheme">
<activity
android:name=".LoginActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.Light.NoTitleBar"
android:windowSoftInputMode="stateHidden"
android:launchMode="singleTop">
<!-- <intent-filter> -->
<!-- <action android:name="android.intent.action.MAIN" /> -->
<!-- <category android:name="android.intent.category.LAUNCHER" /> -->
<!-- </intent-filter> -->
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name=".musicPlayer"
android:label="@string/title_activity_music_player">
<!-- android:theme="@android:style/Theme.DeviceDefault.Light.DarkActionBar" -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".PlayerService" />
<service android:name=".audioService" />
<receiver android:name=".PlayPauseReceiver" />
<receiver android:name=".NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<receiver android:name=".musicPlayer$MusicNoisyReceiver" >
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
<activity
android:name=".singleMusicScreen"
android:label="@string/title_activity_single_music_screen" >
</activity>
</application>
</manifest>
活动:
public class musicPlayer extends DrawerActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
pullToRefresh = (PullRefreshLayout) findViewById(R.id.pullToReresh);
musicListLayout = new RelativeLayout(getApplicationContext());
progressBar = new ProgressBar(getApplicationContext());
pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
editor = pref.edit();
getUser = pref.getString("sharedUser", "");
getPassword = pref.getString("sharedPass", "");
new doLogin().execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_music_player, menu);
return true;
}
@Override
public void onBackPressed() {
// Do Here what ever you want do on back press;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public boolean isFirstItemCompletelyVisible() {
return mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0;
}
@Override
public void onResume() {
super.onResume();
musicList.post(new Runnable() {
@Override
public void run() {
pullToRefresh.setEnabled(isFirstItemCompletelyVisible());
}
});
}
private class doLogin extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPreExecute() {
Intent myIntent = getIntent();
boolean button = myIntent.getBooleanExtra("LoginButton", false);
if (!pref.getBoolean("isCheckBoxChecked", false) && !button) {
Intent intent = new Intent(musicPlayer.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
finish();
cancel(true);
}
if (button) {
getUser = myIntent.getStringExtra("userLogin");
getPassword = myIntent.getStringExtra("passLogin");
}
Log.i("TEST", "User: " + getUser + " pass: " + getPassword);
}
@Override
protected Boolean doInBackground(Void... params) {
try {
Log.i("TEST", "Init");
api = DefaultClientFactory.create(host, getUser, getPassword);
Log.i("TEST", "" + api.getUserInfo());
return true;
} catch (StorageApiException e) {
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (!result) {
Intent intent = new Intent(musicPlayer.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
Toast.makeText(getApplicationContext(), "Invalid E-mail or Password !", Toast.LENGTH_SHORT).show();
} else {
// new backgroundTask().execute();
}
}
}
}
活动启动模式应谨慎使用。
机器人:launchMode =“singleTop”
如果活动的实例出现在任务堆栈的顶部,一个新的实例将无法通过onNewIntent创建,系统将路由你的意图的信息()。如果它不在顶部,则会创建一个新实例。可以创建多个实例,每个实例可以属于不同的任务。(Good post on activity launch mode)
为什么要检查在onPreExecute()共享PREF,然后取消它?检查完成后,更好的方法是执行asynctask。
取消(true)不保证一旦调用它就会停止异步任务。更好的方法是在doInBackground()中添加isCancelled()检查,如果取消,则返回根据需要返回的结果。这将有助于尽早完成asynctask,而无需执行写在那里的任务。
-
在清单中,您可能想要添加android:conifgChanges以更好地处理方向。
机器人:configChanges = [ “MCC”, “MNC”, “区域”, “触屏”, “键盘”, “keyboardHidden”, “导航”, “屏幕布置”, “fontScale”, “uiMode”, “方向”, “屏幕尺寸”, “smallestScreenSize”]
希望这有助于!
你确定它运行了两次还是只有两次运行? –
是的,一切都运行两次,我的两个asynctasks运行两次,onCreate运行两次。 –
请发布清单和活动 –