Load resource (layout) from another apk dynamically - android

I managed to pull the layouts, and i add it to my viewflipper, however, there it is loaded as blank.
The code is,
Resources packageResources;
Context packageContext;
try
{
packageResources = pm.getResourcesForApplication(packageName);
packageContext = this.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE + Context.CONTEXT_IGNORE_SECURITY);
}
catch(NameNotFoundException excep)
{
// the package does not exist. move on to see if another exists.
}
Class layoutClass;
try
{
// using reflection to get the layout class inside the R class of the package
layoutClass = packageContext.getClassLoader().loadClass(packageName + ".R$layout");
}
catch (ClassNotFoundException excep1)
{
// Less chances that class won't be there.
}
for( Field layoutID : layoutClass.getFields() )
{
try
{
int id = layoutID.getInt(layoutClass);
XmlResourceParser xmlResourceLayout = packageResources.getLayout(id);
View v = new View(this, Xml.asAttributeSet(xmlResourceLayout));
this.viewFlipper.addView(v);
}
catch (Exception excep)
{
continue;
}
}
I get no errors, and i debugged and checked. The layout IDs are correct. However, in my viewFlipper its just blank. No warnings or errors i can find.

Finally got it.... Its actually simple !!!!
Here is what i did...
In the target apk, there is only resources and layouts with no application or activity code. I created a class,
public final class ViewExtractor
{
private static final int NUMBER_OF_LAYOUTS = 5;
public static View[] getAllViews(Context context)
{
View[] result = new View[ViewExtractor.NUMBER_OF_LAYOUTS];
result[0] = View.inflate(context, R.layout.layout_0, null);
result[1] = View.inflate(context, R.layout.layout_1, null);
result[2] = View.inflate(context, R.layout.layout_2, null);
result[3] = View.inflate(context, R.layout.layout_3, null);
result[4] = View.inflate(context, R.layout.layout_4, null);
return result;
}
}
Then in my current application, I modified my earlier code. The modification takes place once package has been verified to exist.
// If the package exists then get the resources within it.
// Use the method in the class to get the views.
Class<?> viewExtractor;
try
{
viewExtractor = packageContext.getClassLoader().loadClass(packageName + ".ViewExtractor");
}
catch (ClassNotFoundException excep)
{
continue;
}
View[] resultViews;
try
{
Method m = viewExtractor.getDeclaredMethod("getAllViews", Context.class);
resultViews= (View[])m.invoke(null, new Object[]{packageContext});
for( View v : resultViews)
{
this.viewFlipper.addView(v);
}
}
catch (Exception excep)
{
excep.printStackTrace();
}

You are not inflating a layout. You are creating an empty View and adding it to your ViewFlipper.

I am currently doing this. It only works if a know the packageName of activity or fragment from the .apk that should provide the layout hierarchy (I call this foreign context). And you need to know the name of the layout you want to inflate (e.g. R.layout.mylayout -> "mylayout")
Context c = createPackageContext(foreignPackageName,
Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY); //create foreign context
int resId = c.getResources.getIdentifier(mylayoutName,"layout",foreignPackageName);
LayoutInflater myInflater = LayoutInflater.from(c); //Inflater for foreign context
View myLayout = myInflater.inflate(resId,null,false); //do not attach to a root view

Related

Android - getResources().getIdentifier replacement

In android I am looping through the database and assigning text and image:
Cursor res = myDb.getAllData();
while (res.moveToNext()) {
Actors actor = new Actors();
actor.setName(res.getString(1));
String th = res.getString(11);
Integer thumb = this.getResources().getIdentifier(th, "drawable", "mypackage");
actor.setThumb(R.drawable.th);
}
However Lint suggests not to use getIdentifier - Use of this function is discouraged because resource reflection makes it harder to perform build optimizations and compile-time verification of code.
In database column I have just the image name (string). How can I replace getIdentifier?
Even if I change the DB column maybe directly to R.drawable.imagename, it is still a string and for setThumb I need a drawable.
Ok, so the only solution what I've found is here https://stackoverflow.com/a/4428288/1345089
public static int getResId(String resName, Class<?> c) {
try {
Field idField = c.getDeclaredField(resName);
return idField.getInt(idField);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
and then just calling:
int resID = getResId("icon", R.drawable.class);
This works very well, however some users reports, that after installing the app from Play store (not my app, but any with this method implemented and proguard enabled), after a while it will start throwing NoSuchFieldException, as more resources are mapped to the same class/field.
It can be caused by proguard but not sure. The solution is then to put the old way getResources().getIdentifier to the exception part of code.
You can try this approach:
Rename your resources as follow:
ressourceName00
ressourceName01
ressourceName02 .... and so on,
then use the methode below:
for (int i = 0; i < RessourceQtt; i++) {
Uri path1 = Uri.parse("android.resource://yourPackage Directories/drawable/ressourceName0" + i);
list.add(new CarouselItem(String.valueOf(path1)));
}
You can try this my code three way
// Show message and quit
Application app = cordova.getActivity().getApplication();
String package_name = app.getPackageName();
Resources resources = app.getResources();
String message = resources.getString(resources.getIdentifier("message", "string", package_name));
String label = resources.getString(resources.getIdentifier("label", "string", package_name));
this.alert(message, label);
set icon like that
private int getIconResId() {
Context context = getApplicationContext();
Resources res = context.getResources();
String pkgName = context.getPackageName();
int resId;
resId = res.getIdentifier("icon", "drawable", pkgName);
return resId;
}
this is also
//set icon image
final String prefix = "ic_";
String icon_id = prefix + cursor.getString(cursor.getColumnIndex(WeatherEntry.COLUMN_ICON));
Resources res = mContext.getResources();
int resourceId = res.getIdentifier(icon_id, "drawable", mContext.getPackageName());
viewHolder.imgIcon.setImageResource(resourceId);
I hope this code help for you.
public static int getIcId(String resN, Class<?> c) {
try {
Field idF = c.getDeclaredField(resN);
return idF.getInt(idF);
} catch (Exception e) {
throw new RuntimeException("No resource ID found for: "
+ resN+ " / " + c, e);
}}

Fragment not added to activity when method is called

I have a main activity called Chessboard. Within Chessboard, in the onCreate, I set a fragment activity GameInfoFragment. After this, a call is made to query an SQLite database, immediately after which a method in class SQLiteDataInterpreter is called. From here, a call is made to a method in the GameInfoFragment class, where imageViews in the fragment I set in Chessboard's onCreate should be populated.
When I attempt to start the Chessboard activity, I receive the following error:
Caused by: java.lang.IllegalStateException: Fragment GameInfoFragment{2ef389d9 id=0x7f09008d InfoTest} not attached to Activity
The code in Chessboard's onCreate is the following:
FragmentManager manager = this.getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
if (chessboard.moveCounter % 2 == 0) {
transaction.add(com.zlaporta.chessgame.R.id.game_play_screen, gameInfo, "InfoTest");
} else {
transaction.add(com.zlaporta.chessgame.R.id.game_play_black_screen, gameInfo, "InfoTestBlack");
}
transaction.commit();
Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar);
toolbar.setTitle("Current Game");
setSupportActionBar(toolbar);
DBAdapter boardstateDB = new DBAdapter(chessboard.this);
boardstateDB.open();
Cursor cur = boardstateDB.getAllRows();
if (cur != null && cur.moveToFirst()) {
cur.moveToLast();
String pieceData = cur.getString(cur.getColumnIndex("piecepositions"));
whiteKingMoved = cur.getInt(cur.getColumnIndex("whitekingmoved"));
blackKingMoved = cur.getInt(cur.getColumnIndex("blackkingmoved"));
leftWRMoved = cur.getInt(cur.getColumnIndex("whiterook1moved"));
rightWRMoved = cur.getInt(cur.getColumnIndex("whiterook2moved"));
leftBRMoved = cur.getInt(cur.getColumnIndex("blackrook1moved"));
rightBRMoved = cur.getInt(cur.getColumnIndex("blackrook2moved"));
moveCounter = cur.getInt(cur.getColumnIndex("movecount"));
String madeMoves = cur.getString(cur.getColumnIndex("mademoves"));
storedTakenPieces = cur.getString(cur.getColumnIndex("takenpieces"));
SQLiteDataInterpreter boardRefresher = new SQLiteDataInterpreter();
boardRefresher.refreshBoard(pieceData, madeMoves, chessboard.this, storedTakenPieces);
} else {
boardstateDB.updateGameState("r00 k01 b02 q03 a04 b05 k06 r07 p10 p11 p12 p13 p14 p15 p16 p17 P60 P61 P62 P63 P64 P65 P66 P67 R70 K71 B72 Q73 A74 B75 K76 R77",
0, 0, 0, 0, 0, 0, 0, " ", " ");
Cursor curs = boardstateDB.getAllRows();
curs.moveToLast();
String pieceData = curs.getString(curs.getColumnIndex("piecepositions"));
whiteKingMoved = curs.getInt(curs.getColumnIndex("whitekingmoved"));
blackKingMoved = curs.getInt(curs.getColumnIndex("blackkingmoved"));
leftWRMoved = curs.getInt(curs.getColumnIndex("whiterook1moved"));
rightWRMoved = curs.getInt(curs.getColumnIndex("whiterook2moved"));
leftBRMoved = curs.getInt(curs.getColumnIndex("blackrook1moved"));
rightBRMoved = curs.getInt(curs.getColumnIndex("blackrook2moved"));
moveCounter = curs.getInt(curs.getColumnIndex("movecount"));
String madeMoves = curs.getString(curs.getColumnIndex("mademoves"));
storedTakenPieces = curs.getString(curs.getColumnIndex("takenpieces"));
SQLiteDataInterpreter boardRefresher = new SQLiteDataInterpreter();
boardRefresher.refreshBoard(pieceData, madeMoves, chessboard.this, storedTakenPieces);
And the relevant code in my GameInfoFragment class which is causing problems:
public void setTakenPiece(String[] takenpiecerecord) {
takenPiece = takenpiecerecord;
int c;
for (c = 0; c < takenPiece.length; c++) {
String takenPieceHolder = "t" + c;
String pieceCheck = takenPiece[c];
//System.out.println(square);
int takenPieceHolderID = this.getResources().getIdentifier(takenPieceHolder, "id", getActivity().getPackageName());
ImageView takenPieceHolderSquare = (ImageView) v.findViewById(takenPieceHolderID);
The main line of code that is causing issues is where I try to set the value of takenPieceHolderID in the code directly above.
How can I ensure that my fragment is added so that its imageViews will be populated upon the start of my Chessboard Activity?
You should check if Activity exists and if isAdded() is True
public void setTakenPiece(String[] takenpiecerecord) {
activity = getActivity();
if (isAdded() && activity) {
takenPiece = takenpiecerecord;
int c;
for (c = 0; c < takenPiece.length; c++) {
String takenPieceHolder = "t" + c;
String pieceCheck = takenPiece[c];
//System.out.println(square);
int takenPieceHolderID = this.getResources().getIdentifier(takenPieceHolder, "id", getActivity().getPackageName());
ImageView takenPieceHolderSquare = (ImageView) v.findViewById(takenPieceHolderID);
}}
I use the fragment manager to find the fragment by tag. If it returns null I have problems with fragment creation. This depends on whether my fragment has a valid container, calls an adapter and the adapter is unhappy, or if it calls a view improperly, so double check all. Make sure your container is added to your ViewGroup, if you are using one, and that the container is detached from any parent.
I create my fragments programatically and set tag names that can be searched.
Using debug, be sure that the fragment constructor is called, then make sure onCreateView is called. If so, single step through onCreateView and look for a line that bombs. Make sure the fragment returns a view.
Also be sure what type of fragment you are using, android or android.support.v4.app.Fragment.
At times I have had to use FragmentManager whatever_your_name_is.executePendingTransactions to ensure that the fragment has been added prior to being accessed. Be sure to use the fragment manager that launched the fragment.
That's my brain dump, good luck.

How to do a findViewById (R.id.>> StringVarHere << )?

Searched and working on this a long while - no luck. ( It must be simple ? Thanks for the assist. )
Trying to get / set a screen full of EditTexts' text, but not with the usual, more hard-coded way:
... findViewById (R.id.SomeTextWidgetId) ;
Instead, I'm trying to figure out a reusable way via a variable holding the (String) name_of_widget.
In psuedo code:
findViewById (R.id.>> StringVarHere << ); // how to do that ?
I tried also this findViewById method, but it didn't work (!?)
//// given:
static final String FIELD_TV_FEE = "TextViewFee" ;
static final String FIELD_TV_FOO = "TextViewFoo" ;
static final String FIELD_TV_FUM = "TextViewFum" ;
//// and some arbitrary number more of similar fields
static final String [] ALL_FIELDS = {
FIELD_TV_FEE ,
FIELD_TV_FOO ,
FIELD_TV_FUM // ...
} ;
//// ...
//// this part works
int ResourceID;
String stringVarHere = FIELD_TV_FEE;
//// outputs a correct id, say '0x7f05000f' as in R.id.xxx below
ResourceID = context
.getResources()
.getIdentifier ( stringVarHere,
"id",
context
.getApplicationInfo()
.packageName
) ;
Log.d ("MyClass" , "RESID = " + Integer.toHexString(ResourceID) ) ;
/*
* that's where I'm stuck ^^^ ... how do I do:
*/
String field_name ;
for ( field_name : ALL_FIELDS ) {
(EditText) SomethingLike_a_findViewById(field_name).setText ("Hello Wurld") ;
}
I've tried .setId ...
//// details
<!-- excerpt from working xml layout -->
<EditText
android:id="#+id/TextViewFee"
android:inputType="text"
android:layout ... etc ...
/>
<EditText
android:id="#+id/TextViewFoo"
android:inputType="text"
android:layout ... etc ...
/>
<EditText
android:id="#+id/TextViewFum"
android:inputType="text"
android:layout ... etc ...
/>
As expected, the gen'ed R file has something like this:
// ...
public static final class id {
public static final int TextViewFee=0x7f05000f;
public static final int TextViewFum=0x7f05001c;
public static final int TextViewFoo=0x7f05001d;
// ... etc
Yes, thanks - it makes sense to do it in the activity. I was trying to keep it from getting too code bulky. Here's what I'm doing now, based on your and A-C's helpful suggestions. The intention is to get all the text of fields of a form back in one String[]. (I know I could brute force all the fields too.)
What do you all think about this below - seems very similar to your suggestion, madlymad ? I am wondering if this is a poor design approach ?
public class FoodBar {
private Activity activity;
private Context ctx;
public FoodBar ( Activity _activity ) {
this.activity = _activity;
this.ctx = this.activity.getApplicationContext() ;
}
public String[] getTextFromAllEditTexts () { // the UI views
int res_id = 0;
int i = 0;
String [] retValues = new String [MyClassName.ALL_FIELDS_LENGTH] ;
for (String field : MyClassName.ALL_FIELDS_ALL_VEHICLES) {
res_id = this.ctx.getResources()
.getIdentifier ( field, "id", this.ctx.getPackageName() );
((EditText) this.activity
.findViewById (res_id))
.setText( "Meat and Potatoes" ) ;
// redundant - get it right back to make sure it really went in !
retVal[i++] = ((EditText) this.activity
.findViewById (res_id))
.getText().toString() ;
}
return retVal;
} // end func
} // end class
Then from the Activity class, it's just:
String [] theFields = null;
FoodBar = new FoodBar (this);
try {
theFields = FoodBar.getTextFromAllEditTexts ();
} catch (Exception e) {
Log.d ("OOPS", "There's a big mess in the Foodbar: " + e.toString() );
}
The way you could do it is (as I understand the way you are trying):
This can be in non-Activity (YourClassname.java):
public static int getMyId(Context context, String field) {
return context.getResources().getIdentifier (field, "id", context.getPackageName());
}
in Activity-class:
for ( String field_name : YourClassname.ALL_FIELDS ) {
int resid = YourClassname.getMyId(context, field_name);
if(resid != 0) { // 0 = not found
EditText et = (EditText) findViewById(resid);
if (et != null) {
et .setText ("Hello Wurld") ;
}
}
}
But I think it's better to code in the activity class like:
String packageName = getPackageName();
Resources res = getResources();
for ( String field_name : YourClassname.ALL_FIELDS ) {
int resid = res.getIdentifier (field_name, "id", packageName);
if(resid != 0) {// 0 = not found
EditText et = (EditText) findViewById(resid);
if (et != null) {
et .setText ("Hello Wurld") ;
}
}
}
A-C suggested something along the lines of:
res_id = getResources().getIdentifier (field, "id", getPackageName());
((EditText)findViewById (res_id)).setText("NoLongerFubar");
this DOES work - when I tried it standalone in a test rig. Thanks ! Still not sure what was blowing up, but I suspect it was Context or Resource items not being accessible.
Note that variable names (such as R.id.some_id) are only available at compile time and cannot be accessed from a String value at run time. Since these ids are declared as ints, you might consider using an int[] or List<Integer> to store the ids. Depending on how dynamic your layout is and what you are doing with the Views in it, you might even want to simply create the Views at run time and store an array or List of them without using any ids at all.

Image in listview via database+assets

I have a database which has a name of an animal, and in an other column a sound of the animal.
The listview works fine, and now I would like to extend it with an image out of the assets.
For this I've read about how to get the assets data and use it.
An example I've tried worked fine for me.
Now I want this "assets" code (at least I think I want this) in the extended BaseAdapter class.
Unfortunately I'm doing something wrong as I can't use the getAssets() in the BaseAdapter.
The problem starts in the try-catch block: " getAssets " doesn't get recognized
Which way would I think of solving this?
Creating another class in which this assets code can run in an extended "Activity"?
Or are there better ways of showing an image via database info in a listview?
Thank you for your support in my quest to get familiar with Android / Java.
public View getView(int position, View convertView, ViewGroup parent) {
// get view reference
View view = convertView;
// if null
if(view == null) {
// inflate new layout
view = mInflater.inflate(R.layout.layout_list_item, null);
// create a holder
ViewHolder holder = new ViewHolder();
// find controls
holder.txtName = (TextView)view.findViewById(R.id.txtName);
holder.txtPicture = (ImageView)view.findViewById(R.id.txtPicture);
// set data structure to view
view.setTag(holder);
}
// get selected user info
UserInfo userInfo = mListUserInfo.get(position);
// if not null
if(userInfo != null) {
// query data structure
ViewHolder holder = (ViewHolder)view.getTag();
// set data to display
holder.txtName.setText(userInfo.getName() + ", " + userInfo.getPicture() );
try {
// get input stream
InputStream ips = getAssets().open( userInfo.getPicture() + ".jpg");
Log.d("Imageloading", "Reading: " + ips);
// load image as Drawable
Drawable d = Drawable.createFromStream(ips, null);
// set image to ImageView
holder.txtPicture.setImageDrawable( d );
}
catch(IOException ex) {
Log.e("Imageloading", "Could not load '" + ex.getMessage()+ "'!");
}
}
// return view
return view;
}
I've just edited the code.
To solve the getAssets() thing I've done the following:
holder.txtPicture.setImageDrawable( getSomePicture(null, userInfo.getPicture() + ".jpg") );
public Drawable getSomePicture(Context myContext, String WhichPicture) throws IOException {
// get input stream
InputStream ips = myContext.getAssets().open( WhichPicture );
Log.d("Imageloading", "Reading: " + ips);
// load image as Drawable
Drawable d = Drawable.createFromStream(ips, null);
return d;
}
This still is not the solution, researching some more....
Found an interesting source for Lazy Loading
to call getAssets() function in non-activity class you need reference to Context. In your updated code you called function 'getSomePicture()' and passed null to myContext parameter. that means your code will fail because you have myContext.getAssets() later in your method code.
try to do this in your getView method:
Context context = getContext();
holder.txtPicture.setImageDrawable( getSomePicture(context, userInfo.getPicture() + ".jpg") );
You won't have access to the getAssets() method because that is a method that only the Context (and it's subclass, Activity) have. What I find is easiest here is to make your BaseAdapter subclasses private inner classes of the Activity in which it is to be used. That way, you'll have access to the getAssets() method.
Here is what this might look like:
public class YourExampleActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
}
private class YourListAdapter extends BaseAdapter {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// get view reference
View view = convertView;
// if null
if(view == null) {
// inflate new layout
view = mInflater.inflate(R.layout.layout_list_item, null);
// create a holder
ViewHolder holder = new ViewHolder();
// find controls
holder.txtName = (TextView)view.findViewById(R.id.txtName);
holder.txtPicture = (ImageView)view.findViewById(R.id.txtPicture);
// set data structure to view
view.setTag(holder);
}
// get selected user info
UserInfo userInfo = mListUserInfo.get(position);
// if not null
if(userInfo != null) {
// query data structure
ViewHolder holder = (ViewHolder)view.getTag();
// set data to display
holder.txtName.setText(userInfo.getName() + ", " + userInfo.getPicture() );
try {
// get input stream
InputStream ips = getAssets().open( userInfo.getPicture() + ".jpg");
Log.d("Imageloading", "Reading: " + ips);
// load image as Drawable
Drawable d = Drawable.createFromStream(ips, null);
// set image to ImageView
holder.txtPicture.setImageDrawable( d );
}
catch(IOException ex) {
Log.e("Imageloading", "Could not load '" + ex.getMessage()+ "'!");
}
}
// return view
return view;
}
// Override other key methods of BaseAdapter here
}
}
Alternatively, you could take in a Context object in the constructor when the BaseAdapter subclass is instantiated, and keep a reference to that with which to call getAssets() on. Please post a comment if you need an example of this.

android listview getting correct icons

I have ListView with icons. Every ListView row either has a different icon or or doesn't have an icon.
I am able to get correct icons for rows which should have them but problem is, in rows where there shouldn't be any icon there is some icon.
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_item, null);
TextView title = (TextView) vi.findViewById(R.id.name);
ImageView icon = (ImageView) vi.findViewById(R.id.icon);
HashMap<String, String> item = new HashMap<String, String>();
item = data.get(position);
String imgPath = ASSETS_DIR + item.get(myTable.KEY_PIC) + ".png";
try {
Bitmap bitmap = BitmapFactory.decodeStream(vi
.getResources().getAssets().open(imgPath));
icon.setImageBitmap(bitmap);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
title.setText(item.get(myTable.KEY_NAME));
return vi;
}
KEY_PIC always has a value and if KEY_PIC's value is equal to some icon's filename only then it should show icon. I cant figure out how to code it. I should do something in if-else i guess.
Firstly you've done a bad thing by putting HashMap<String, String> item = new HashMap<String, String>(); in your getView(). Right now you're making a new one of these for every row re-shown and that's unneeded. just delete it and use:
String imgPath = ASSETS_DIR + data.get(position).get(myTable.KEY_PIC) + ".png";
Quite honestly i can't understand how it is that you see an icon if you claim that your path doesn't lead to anything if the row isn't supposed to be showing something. If it worked well, then you could simply catch the exception that might occur upon setting and do nothing with it. Looking into the actual value of data at that position should yield insight. if it were me, i'd just put null at those positions.
A temporary alternative solution is to make a boolean array for each of the positions in your listview and then only perform your icon setting if the value at that position checks out.
boolean[] varIcon = {
true,
false,
false,
true,
false,
true };
// ...
// then in the getView() now;
if (varIcon[position] == true) {
String imgPath = ASSETS_DIR + data.get(position).get(myTable.KEY_PIC) + ".png";
try {
Bitmap bitmap = BitmapFactory.decodeStream(vi
.getResources().getAssets().open(imgPath));
icon.setImageBitmap(bitmap);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The likely problem is that the views are getting recycled and you're never clearing the image that was previously set, try this to prove it:
String imgPath = ASSETS_DIR + item.get(myTable.KEY_PIC) + ".png";
try {
Bitmap bitmap = BitmapFactory.decodeStream(vi
.getResources().getAssets().open(imgPath));
icon.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
icon.setImageDrawable(null);
}
However, relying on exception handling for a perfectly valid outcome is not a good practice (nor performance friendly). I would recommend you make your myTable.KEY_PIC column return null, and then you can do:
String imageName = item.get(myTable.KEYP_PIC);
if (imageName == null) {
icon.setImageDrawable(null);
} else {
//your code
}
Which is much cleaner.

Categories

Resources