I am trying to run this Android unit test, following this tutorial ::
http://developer.android.com/resources/tutorials/testing/helloandroid_test.html
and in doing so get a SuperNotCalledException
Here's the test class code ::
package com.example.helloandroid2.test;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.TextView;
import com.example.helloandroid2.HelloAndroid2Activity;
public class HelloAndroid2Test extends ActivityInstrumentationTestCase2<HelloAndroid2Activity>
{
private HelloAndroid2Activity mActivity;
private TextView mView;
private String resourceString;
public HelloAndroid2Test()
{
super("com.example.helloandroid2", HelloAndroid2Activity.class);
}
#Override
protected void setUp() throws Exception
{
super.setUp();
mActivity = this.getActivity();
mView = (TextView) mActivity.findViewById(com.example.helloandroid2.R.id.textview);
resourceString = mActivity.getString(com.example.helloandroid2.R.string.hello);
}
public void testPreconditions()
{
assertNotNull(mView);
}
public void testText()
{
assertEquals(resourceString,(String)mView.getText());
}
}
The class I'm actually testing ::
package com.example.helloandroid2;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid2Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.main);
}
}
I've set the project API levels at 2_3_1 and am using an avd set at the same.
Am running Eclipse with ADT on Windows Vista.
All wisdom greatfully recieved. Thanks in advance.
Chris
Your onCreate() method in HelloAndroid2Activity needs to call super.onCreate(savedInstanceState);
public class HelloAndroid2Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Related
I created a ListDialog extending a DialogFragment class and I have a problem with understanding of this code in the DijalogX class
((MainActivity)getActivity()).setTextField(selectedItem);
I understand that with this code above I put selected String variable to the setTextField method as an argument and after that this variable is showed in TextView on MainActivity class.
My questions:
Why I need a cast from getActivity() to the MainActivity and how I get access from DijalogX(fragment) to the method setTextField in MainActivity? Please explain a little about this process.
I also tried instead of ((MainActivity)getActivity()).setTextField(selectedItem)
use an Interface and everything works nice and I got the same resoult but I am wondering what is better solution here Interface or ((MainActivity)getActivity()).setTextField(selectedItem)?
MainActivity
package com.example.dezox.dijaloglist;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity{
private Button btnStartDialog;
private TextView tvSelectedOption;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWidgets();
setupListener();
}
private void initWidgets() {
btnStartDialog = findViewById(R.id.btnDialog);
tvSelectedOption = findViewById(R.id.tvselectedOption);
}
private void setupListener() {
btnStartDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DijalogX dijalogX = new DijalogX();
dijalogX.show(getSupportFragmentManager(), "dx");
tvSelectedOption.setText("");
}
});
}
public void setTextField(String odabrano){
tvSelectedOption.setText(odabrano);
}
public String getTextField(){
return tvSelectedOption.getText().toString();
}
}
DijalogX
package com.example.dezox.dijaloglist;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
public class DijalogX extends DialogFragment {
private String[] languageList;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initListResource();
}
private void initListResource() {
languageList = getResources().getStringArray(R.array.language_list);
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
android.R.style.Theme_Material_Dialog_Alert)
.setTitle("Select Language: ")
.setItems(languageList, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String selectedItem = languageList[which];
//THIS PART OF THE CODE I DONT UNDERSTAND:
((MainActivity)getActivity()).setTextField(selectedItem);
}
});
return builder.create();
}
}
You have declared a method in MainActivity called setTextField. If you called
Activity a = getActivity();
you would not be able to call your custom method (it is on your derived class, not the base Activity class).
a.setTextField(selectedIte); // WON'T WORK - NO SUCH METHOD
If instead you call
MainActivity ma = (MainActivity)getActivity();
it is now cast as your derived class and you can then call
ma.setTextField(selectedItem);
Doing it in two lines like this is the same as calling the one-liner in your code
((MainActivity)getActivity()).setTextField(selectedItem);
As far as casting vs. an interface, an interface is a bit more flexible of an approach. If you tried to use this fragment in a different activity (not MainActivity) the casting approach would fail. If you are only ever going to use the fragment in this Activity then either would work.
I call FacebookSdk.sdkInitialize(getApplicationContext()) in my GlobalActivity.
public class GlobalActivity extends Application {
#Override
public void onCreate() {
super.onCreate();
FacebookSdk.sdkInitialize(getApplicationContext());
AppEventsLogger.activateApp(this);
}
}
Do I need to call it again each time I am using facebook sdk?
I have a Fragment with a LoginButton.
public class LoginFragment extends Fragment{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getActivity().getApplicationContext());
}
}
Simple way is Initialize once in Application class thats enough. when new activity created FacebookSdk automatically Initialized.
import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;
public class ApplicationName extends Application {
#Override
public void onCreate() {
super.onCreate();
// Initialize the SDK before executing any other operations,
FacebookSdk.sdkInitialize(getApplicationContext());
AppEventsLogger.activateApp(this);
}
}
I have four classes:
MainActivity extends AppCompactActivity
MainAsyncTask extends AsyncTask<String, String, List>
Intermediate extends MainAsyncTask and have two functions. (FuncA, FuncB)
Leaf extends Intermediate and implementation of doInBackground() and onPostExecute().
When I run the application it prompts:
Unable to instantiate activity ComponentInfo{}: android.os.NetworkonMainThreadException.
How can I get rid off the Error. As far as My understanding is concerned, doInBackground() and onPostExecute()should be implemented in MainAsyncTask class?
Classes are :
MianActivity.java
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Leaf object = new Leaf();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button fab = (Button) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
object.execute();
}
});
}
}
MainAsyncTask.java
import android.os.AsyncTask;
public class MainAsync extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(String... text) {
}
}
Intermediate.java
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
public class Intermediate extends MainAsync{
public Document FunA(){
System.out.println("Printed FunA()");
String url = "http://blogs.tribune.com.pk/story/37034/zakir-naik-has-a-large-following-in-pakistan-should-we-be-alarmed/";
Document doc = null;
try {
doc = Jsoup.connect(url).timeout(10 * 1000).get();
} catch (IOException e) {
e.printStackTrace();
}
return doc;
}
public void FunB(){ System.out.println("Printed FunB()");}
}
}
Leaf.java
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Leaf extends Intermediate{
Document HTM = FunA();
public void FunC() {
String heading = "";
System.out.println("Printed FunC()");
Elements seep = HTM.select("h1");
for (Element foo : seep) {
heading = foo.text();
System.out.println(heading);
break;
}
}
public void FunD() {
System.out.println("Printed FunD()");
}
public void FunE() {
System.out.println("Printed FunE()");
}
#Override
protected String doInBackground(String... params) {
FunB();FunC();FunD();FunE();
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(String... text) {
}
}
The purpose of doing in this way is to add FuncA and FuncB along with AsyncTask methods in one class that is Leaf class.
In the absence of a stack trace I would say:
Initiating your Leaf class causes the HTM variable to be initiated.
The HTM variable is initiated by calling the FunA method.
The FunA method runs network accessing code and is not running inside DoInBackground (and therefore running on the main thread).
Your network code can only be run inside DoInBackground if you wish to not get a NetworkOnMainThread Exception.
The exception is thrown before you even start the AsyncTask as just the act of creating it causes the FunA code to run.
Move this line inside DoInBackground so it runs when the AsyncTask is executed and not when it is created.
Document HTM = FunA();
On a separate note, your class hierarchy is very convoluted. You do not need Intermediate or Leaf classes. All that code could be easily moved to the MainAsync class and so would be much easier to understand.
it is probably an noob question but still. I need to my main activity class will use other class to do some code. This class uses function that are from Activity like getPackageName(), new Intent etc.
So I need some help with this, for example what I need it to setContentView via class. How do I do this?
Main Acticity:
package com.example.testapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
SetContentView cn = new SetContentView();
cn.MySetContentView(R.layout.activity_main);
}
}
SetViewClass:
package com.example.testapp;
public class SetContentView
{
void MySetContentView(int activityMain)
{
setContentView(R.layout.activity_main); //no set content view if not activity
}
}
public class MainActivity extends Activity
{
private static MainActivity instance;
public static MainActivity getInstance() {
return instance;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance=this;
}
}
public class OtherClass
{
protected void someMethod() {
MainActivity ma= MainActivity.getInstance();
//use ma methods...
}
}
If I'm getting it right, you could try having a root class extending Activity and holding your methods, and then extending it in MainActivity:
public class Helper extends Activity {
... // your methods, e.g. MySetContentView
}
and then:
public class MainActivity extends Helper {
... // any call to methods in Helper
}
This can be useful if you have a lot of activities that share the same code - you can have them all extending the same Helper class, and still being Activities.
In your case:
public class Helper extends Activity {
public void mySetContentView(int layout) {
setContentView(layout)
}
}
and then:
public class MainActivity extends Helper {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mySetContentView(R.layout.your_layout);
}
I have a TextView with the id android:id="#+id/yazi", and I have a button that has build in android:OnClick="gonderB"
and I can complie this code:
package com.seri.bir;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
Bilmez b;
TextView t;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b = new Bilmez();
t = (TextView) findViewById(R.id.yazi);
}
public void gonderB (View v,TextView t,Bilmez b){
String s = " ..."+this;
b.yaziYaz(v,s,t);
}
}
class Bilmez {
public void yaziYaz(View v,String s,TextView t){
t.setText(s);
}
}
However I have an error.
Can I setText in another class?
You can overwrite onClick of the activity. Avoid the using of the android:OnClick="gonderB" line in the xml file. I think it is better to implement the onClickListener and attach it to View Objects within your code.
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
Bilmez b;
TextView t;
Button bt;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b = new Bilmez();
t = (TextView) findViewById(R.id.yazi);
Button bt = (Button) findViewById(R.id.btn);
bt.setOnClickListener(this);
}
#Override
public void onClick(View clickedView) {
switch (clickedView.getId()) {
case R.id.btn:
String s = "...." + this;
b.changeText(t,s);
break;
}} //end of main class }
In the changeText method you change the text of the TextView. This method can if be placed in another class if you like that.
class Bilmez {
public void changeText(TextView t, String s){
t.setText(s);
}
}
Perhaps what you are experiencing is a need to run the function on the UI thread?
public void yaziYaz(View v,final String s,final TextView t) {
runOnUiThread(new Runnable() {
public void run() {
t.setText(s);
}
});
}
i think you should do that:
public void gonderB (new View v,TextView t,Bilmez b){
String s = " ..."+this;
b.yaziYaz(v,s,t);
}