如何将Enum对象添加到Android Bundle?
答案 0 :(得分:636)
枚举是可序列化的,所以没有问题。
鉴于以下枚举:
enum YourEnum {
TYPE1,
TYPE2
}
软件包:
// put
bundle.putSerializable("key", YourEnum.TYPE1);
// get
YourEnum yourenum = (YourEnum) bundle.get("key");
意图:
// put
intent.putExtra("key", yourEnum);
// get
yourEnum = (YourEnum) intent.getSerializableExtra("key");
答案 1 :(得分:159)
我知道这是一个老问题,但我遇到了同样的问题,我想分享一下我是如何解决它的。关键是米格尔所说的:枚举是可序列化的。
鉴于以下枚举:
enum YourEnumType {
ENUM_KEY_1,
ENUM_KEY_2
}
把:
Bundle args = new Bundle();
args.putSerializable("arg", YourEnumType.ENUM_KEY_1);
答案 2 :(得分:36)
为了完整起见,这是一个完整的例子,说明如何从包中输入和获取枚举。
鉴于以下枚举:
enum EnumType{
ENUM_VALUE_1,
ENUM_VALUE_2
}
您可以将枚举放入捆绑包中:
bundle.putSerializable("enum_key", EnumType.ENUM_VALUE_1);
然后回复:
EnumType enumType = (EnumType)bundle.getSerializable("enum_key");
答案 3 :(得分:29)
我用kotlin。
companion object {
enum class Mode {
MODE_REFERENCE,
MODE_DOWNLOAD
}
}
然后进入意图:
intent.putExtra(KEY_MODE, Mode.MODE_DOWNLOAD.name)
当你净获得价值时:
mode = Mode.valueOf(intent.getStringExtra(KEY_MODE))
答案 4 :(得分:16)
最好从myEnumValue.name()传递它作为字符串并从YourEnums.valueOf(s)恢复它,否则必须保留枚举的顺序!
答案 5 :(得分:6)
另一种选择:
public enum DataType implements Parcleable {
SIMPLE, COMPLEX;
public static final Parcelable.Creator<DataType> CREATOR = new Creator<DataType>() {
@Override
public DataType[] newArray(int size) {
return new DataType[size];
}
@Override
public DataType createFromParcel(Parcel source) {
return DataType.values()[source.readInt()];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.ordinal());
}
}
答案 6 :(得分:2)
使用bundle.putSerializable(String key,Serializable s)和bundle.getSerializable(String key):
enum Mode = {
BASIC, ADVANCED
}
Mode m = Mode.BASIC;
bundle.putSerializable("mode", m);
...
Mode m;
m = bundle.getSerializable("mode");
文档:http://developer.android.com/reference/android/os/Bundle.html
答案 7 :(得分:1)
有一点需要注意 - 如果您使用#include<stdio.h>
#include<dirent.h>
#include<sys/stat.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>
//Compile: gcc dreamduplicatefinder.c -o dreamduplicatefinder.exe
//Run: ./dreamduplicateFinder.exe parent_dir filename...
#define false 0
#define true 1
int duplicateCount = 0;
int FindDuplicates(char* path, char* fileName);
int CompareFiles(char* originalFile, char* currFile);
int main(int argc, char *argv[])
{
//Two additional arguments are expected: Parent dir, file to find duplicates of...
if (argc != 3)
{
printf("Usage: %s 'Base Directory' 'File Name'\n", argv[0]);
return -1;
}
//argv[1] = base dir, argv[2] = file to find duplicates of; e.g argv[1] = /home,
//argv[2] = "file.txt"...
FindDuplicates(argv[1], argv[2]);
printf("\n\nFound %d duplicate(s)\n", duplicateCount);
return 0;
}
int FindDuplicates(char* path, char* fileName)
{
DIR *dir;
struct dirent *dp;
struct dirent *result;
struct stat statp;
char absoluteFilePath[255];
if ((dir = opendir(path)) == NULL)
{
//printf(dir); //error could becuase trying to open shortcut or corrupt folder.
printf("%s\n",path);
perror("Failed to open directory");
return -1;
}
while ((dp = readdir(dir)) != NULL)
{
//readdir returns . and .. which we should ignore...
if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."))
{
//find file full path, relative to base path. e.g, a /home/file.txt...
//copy path to absoluteFilePath...
strcpy(absoluteFilePath, path);
//append / at end...
strcat(absoluteFilePath, "/");
//append filename to path...
strcat(absoluteFilePath, dp->d_name);
//check if the current file is actually file or dir...
stat(absoluteFilePath, &statp);
if (S_ISDIR(statp.st_mode)) //is a directory...
{
//recurse through this dir...
FindDuplicates(absoluteFilePath, fileName);
}
else if (S_ISREG(statp.st_mode)) //is a file...
{
//check for duplicates here...
//compare current file with the file specified by user...
if (strcmp(fileName, absoluteFilePath))
{
if (CompareFiles(fileName, absoluteFilePath))
{
//yes, duplicate; print it...
printf("%s\n", absoluteFilePath);
duplicateCount++;
}
}
} //end else if (S_ISREG(statp.st_mode))...
} //if (strcmp(dp->d_name, ".") && strcmp(dp->d_name,".."))...
} //end while...
closedir(dir);
return 0;
}
int CompareFiles(char* originalFile, char* currFile)
{
//two step comparison: (1) first check size; if not same, return false.
//If equal, (2) compare file content.If equal, return true, false otherwise...
struct stat statOriginal, statCurr;
stat(originalFile, &statOriginal);
stat(currFile, &statCurr);
//Step 1...
if ((int)statOriginal.st_size != (int)statCurr.st_size) //size not same...
return false;
//Step 2...
//size matches, files can be same; confirm it by matching both file contents...
int fdOriginal = open(originalFile, O_RDONLY);
int fdCurr = open(currFile, O_RDONLY);
if (fdOriginal == -1 || fdCurr == -1)
return false; //error occurred, not sure if file is duplicate...
//we will read file in small chunks and compare...
int chunkSize = 1024, bytesRead;
char *bufferOriginal = (char*)malloc(chunkSize * sizeof(char));
char *bufferCurr = (char*)malloc(chunkSize * sizeof(char));
while (true)
{
//read file in chunk...
bytesRead = read(fdOriginal, bufferOriginal, chunkSize);
if (bytesRead <= 0)
break; //end of file...
bytesRead = read(fdCurr, bufferCurr, bytesRead);
//compare buffer...
if (strcmp(bufferOriginal, bufferCurr)) //if content not matching...
return false;
}
return true;
}
将#include "stdafx.h" //there is nothing in this header
#include<stdio.h>
#include<dirent.h>
#include<sys/stat.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//Compile: gcc <name of this file>.cpp -o <nameOfThisFile>.exe
//Run: <nameOfThisFile> parent_dir filename...
#define false 0
#define true 1
int duplicateCount = 0;
int FindDuplicates(char* path, char* fileName);
int CompareFiles(char* originalFile, char* currFile);
int main(int argc, char *argv[])
{
//Two additional arguments are expected: Parent dir, file to find duplicates of...
if (argc != 3)
{
printf("Usage: %s 'Base Directory' 'File Name'\n", argv[0]);
return -1;
}
//argv[1] = base dir, argv[2] = file to find duplicates of; e.g argv[1] = /home,
//argv[2] = "file.txt"...
FindDuplicates(argv[1], argv[2]);
printf("\n\nFound %d duplicate(s)\n", duplicateCount);
return 0;
}
int FindDuplicates(char* path, char* fileName)
{
DIR *dir;
struct dirent *dp;
struct dirent *result;
struct stat statp;
char absoluteFilePath[255];
if ((dir = opendir(path)) == NULL)
{
//possibly trying to open shortcut or corrupt folder typically.
printf("Failed to open directory %s \n",path);
return -1;
}
while ((dp = readdir(dir)) != NULL)
{
//readdir returns . and .. which we should ignore...
if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."))
{
//find file full path, relative to base path. e.g, a /home/file.txt...
//copy path to absoluteFilePath...
strcpy(absoluteFilePath, path);
//append / at end...
strcat(absoluteFilePath, "/");
//append filename to path...
strcat(absoluteFilePath, dp->d_name);
//check if the current file is actually file or dir...
stat(absoluteFilePath, &statp);
if (S_ISDIR(statp.st_mode)) //is a directory...
{
//recurse through this dir...
FindDuplicates(absoluteFilePath, fileName);
}
else if (S_ISREG(statp.st_mode)) //is a file...
{
//check for duplicates here...
//compare current file with the file specified by user...
if (strcmp(fileName, absoluteFilePath))
{
if (CompareFiles(fileName, absoluteFilePath))
{
//yes, duplicate; print it...
printf("This is a duplicate! %s\n", absoluteFilePath);
duplicateCount++;
}
}
} //end else if (S_ISREG(statp.st_mode))...
} //if (strcmp(dp->d_name, ".") && strcmp(dp->d_name,".."))...
} //end while...
closedir(dir);
return 0;
}
int CompareFiles(char* originalFile, char* currFile)
{
//two step comparison: (1) first check size; if not same, return false.
//If equal, (2) compare file content.If equal, return true, false otherwise...
struct stat statOriginal, statCurr;
stat(originalFile, &statOriginal);
stat(currFile, &statCurr);
//Step 1...
if ((int)statOriginal.st_size != (int)statCurr.st_size) //size not same...
return false;
FILE* fdOriginal;
if (fdOriginal = fopen(originalFile, "r")) {
if (fdOriginal == NULL) { fputs("File error", stderr); return false; }
}
else return false; //error occurred, not sure if duplicate
FILE* fdCurr;
if (fdCurr = fopen(currFile, "r")) {
if (fdCurr == NULL) { fputs("File error", stderr); return false; }
}
else return false;
int chunkSize = 1024, objsRead;
char *bufferOriginal = (char*)malloc(chunkSize * sizeof(char));
if (bufferOriginal == NULL) { fputs("Memory error for buff orig", stderr); exit(2); }
char *bufferCurr = (char*)malloc(chunkSize * sizeof(char));
if (bufferCurr == NULL) { fputs("Memory error for buff curr", stderr); exit(2); }
while (true)
{
//read file in chunk...
//std::size_t fread( void* buffer, std::size_t size, std::size_t count, std::FILE* stream );
objsRead = fread(bufferOriginal, sizeof(char), chunkSize , fdOriginal);
if (objsRead <= 0)
break; //end of file...
objsRead = fread(bufferCurr, sizeof(char), objsRead, fdCurr);
//compare buffer...
if (strcmp(bufferOriginal, bufferCurr)) //if content not matching...
return false;
}
return true;
}
添加到通知中,则可能会遇到以下问题:
bundle.putSerializable
要解决此问题,您可以执行以下操作:
Bundle
然后可以这样使用:
*** Uncaught remote exception! (Exceptions are not yet supported across processes.)
java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object.
...
答案 8 :(得分:1)
对于意图,您可以使用以下方式:
意图:科特林
FirstActivity:
val intent = Intent(context, SecondActivity::class.java)
intent.putExtra("type", typeEnum.A)
startActivity(intent)
SecondActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//...
val type = (intent.extras?.get("type") as? typeEnum.Type?)
}
答案 9 :(得分:1)
我创建了Koltin扩展名:
key
创建一个包并添加:
fun Bundle.putEnum(key: String, enum: Enum<*>) {
this.putString( key , enum.name )
}
inline fun <reified T: Enum<T>> Intent.getEnumExtra(key:String) : T {
return enumValueOf( getStringExtra(key) )
}
并获取:
Bundle().also {
it.putEnum( "KEY" , ENUM_CLAS.ITEM )
}
答案 10 :(得分:0)
一种简单的方法,将整数值赋给枚举
请参阅以下示例:
public enum MyEnum {
TYPE_ONE(1), TYPE_TWO(2), TYPE_THREE(3);
private int value;
MyEnum(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
发件人方:
Intent nextIntent = new Intent(CurrentActivity.this, NextActivity.class);
nextIntent.putExtra("key_type", MyEnum.TYPE_ONE.getValue());
startActivity(nextIntent);
接收方:
Bundle mExtras = getIntent().getExtras();
int mType = 0;
if (mExtras != null) {
mType = mExtras.getInt("key_type", 0);
}
/* OR
Intent mIntent = getIntent();
int mType = mIntent.getIntExtra("key_type", 0);
*/
if(mType == MyEnum.TYPE_ONE.getValue())
Toast.makeText(NextActivity.this, "TypeOne", Toast.LENGTH_SHORT).show();
else if(mType == MyEnum.TYPE_TWO.getValue())
Toast.makeText(NextActivity.this, "TypeTwo", Toast.LENGTH_SHORT).show();
else if(mType == MyEnum.TYPE_THREE.getValue())
Toast.makeText(NextActivity.this, "TypeThree", Toast.LENGTH_SHORT).show();
else
Toast.makeText(NextActivity.this, "Wrong Key", Toast.LENGTH_SHORT).show();
答案 11 :(得分:0)
我认为将enum转换为int(对于普通的枚举)然后在bundle上设置是最简单的方法。喜欢这个意图代码:
myIntent.PutExtra("Side", (int)PageType.Fornt);
然后检查状态:
int type = Intent.GetIntExtra("Side",-1);
if(type == (int)PageType.Fornt)
{
//To Do
}
但不适用于所有枚举类型!
答案 12 :(得分:-31)
从ordinal()传递int
。从值[]恢复它。